<br />
<b>Deprecated</b>:  The each() function is deprecated. This message will be suppressed on further calls in <b>/home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php</b> on line <b>456</b><br />
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="./pretty-feed.xsl" type="text/xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title></title>
	<subtitle></subtitle>
	<link href="/feed.xml" rel="self" type="application/atom+xml" />
	<link href="" rel="alternate" type="text/html"/>
	<author>
		<name></name>
	</author>
	
	<updated>2017-12-23T00:00:00Z</updated>
	
	<id>/</id>
		<entry>
			<title>Refactoring Your Way to a Design System</title>
			<link href="/posts/refactoring-your-way-to-a-design-system/"/>
			<updated>2017-12-23T00:00:00Z</updated>
			<id>/posts/refactoring-your-way-to-a-design-system/</id>
			<content type="html"><![CDATA[
				<p>I love refactoring code. Absolutely love it. There’s something about taking a piece of UI or a bit of code and reworking it in a way that is simpler, modular, and reusable that makes me incredibly happy.</p>
<p>I also love design systems work. It gives <a href="https://24ways.org/2017/design-systems-and-hybrids/">hybrids like me</a> a home. It seems like <a href="https://www.designbetter.co/design-systems-handbook">everyone</a> <a href="https://medium.com/twitter-design-research/looking-to-horizon-why-we-built-a-design-system-841d0a9125be">is</a> <a href="http://bradfrost.com/blog/post/design-system-frictions/">talking</a> about design systems right now. Design systems teams are perfect for those who enjoy doing architectural work and who straddle the line between designer and developer.</p>
<p>Una Kravets recently identified some of the reasons that <a href="https://24ways.org/2017/why-design-systems-fail/">design systems fail</a>, and chief among them are lack of buy-in, underlying architecture, and communication. While it’s definitely easier to establish these before project work begins, that doesn’t mean it is the only path to success.</p>
<p>It’s a privilege to work on a greenfield project, and one that is not afforded to many. Companies with complex and/or legacy codebases may not be able to support a full rewrite of their product. In addition, many people feel overwhelmed at the thought of creating a complete system and are at a loss of how or where to even begin the process.</p>
<p>This is where refactoring comes into play.</p>
<p>According to Martin Fowler, “refactoring is the process of changing a software system in such a way that it does not alter the external behavior of the code yet improves its internal structure.” It’s largely invisible work, and if you do it right, the end user will never know the difference. What it will do is provide a decent foundation to begin more systematic work.</p>
<h2>Build a solid foundation</h2>
<p>When I was first asked to create <a href="https://medium.com/git-out-the-vote/pantsuit-the-hillary-clinton-ui-pattern-library-238e9bf06b54">Pantsuit</a>, the design system for Hillary for America, I was tasked with changing our codebase to be more modular and scalable, without changing the behavior or visual design of the UI. We needed a system in place that would allow for the rapid creation of new projects while maintaining a consistent visual language. In essence, I was asked to refactor our code into a design system.</p>
<p>During that refactor, I focused the majority of my efforts on creating a scalable architecture based on the UI components in a single workflow. Since I needed to maintain a 1:1 parity with production, the only changes I <em>could</em> create were under-the-hood. I started with writing coding standards and deciding on a CSS architecture that I would then use as I rewrote sections of the codebase.</p>
<p>If you already have these in place, great! If not, then this is an excellent place to start. Even if your dream of a design system is never fully realized, having a coding philosophy and architecture in place will still have far-reaching benefits and implications.</p>
<p>I want to note that if your refactor includes creating new coding standards or a CSS architecture, don’t try to switch everything over right away. Instead, focus on a single new feature and isolate/encapsulate your work from the rest of the codebase.</p>
<h2>Focus on the features</h2>
<blockquote>
<p>The key principle to cleaning up a complex codebase is to always refactor in the service of a feature. - Max Kanat-Alexander</p>
</blockquote>
<p>Refactoring for the sake of refactoring can easily lead to accusations of misused time and lack of results. Another danger of refactoring is that it can turn into <a href="https://www.hanselman.com/blog/YakShavingDefinedIllGetThatDoneAsSoonAsIShaveThisYak.aspx">yak-shaving</a> if you aren’t disciplined in your approach. To that end, tying your refactored components to feature work is a great way to limit scope and reduce the rest of unintended changes.</p>
<p>For example, the initial work on Pantsuit focused only on components related to the donations flow. Every line of code I wrote was in service to improving the maintainability and modularity of that UI. Because we didn’t have any standards in place, I started with those. From there, I identified all the components present in every step of the donations flow, which included some type styles, buttons, form inputs and error states. Then came the refactor of each individual component. Finally, I reintegrated the newly refactored components into the existing donations flow and tested it against production, checking for visual and behavioral diffs. At the end of this process, I had the beginning of a design system that would grow to serve over 50 applications, and a case study to demonstrate its effectiveness.</p>
<p>Ideally, you’ll want to get buy-in from your stakeholders and product owners before you begin any design systems work. However, in the absence of buy-in, linking your work to new feature development is a good way to both limit the scope of your refactor and jump start component creation.</p>
<p>In addition, if you’re still trying to convince your team of the benefits of a design system, starting small and using the newly refactored, feature-driven work as a case study is one way showcase a design systems’ value. By providing a concrete example of how working towards a design system contributed to the project’s success, you’re gathering the data necessary to secure buy-in for a larger-scale effort. It’s a great way to show value, rather than just talking about it.</p>
<h2>Show, don’t tell</h2>
<p>Perhaps the most important thing you can do for any design system is to document it. The key is to create a frictionless way to keep the documentation up-to-date, otherwise no one will contribute to it, and in turn, it will become obsolete and useless.</p>
<p>There are lots of tools out there to help you get started documenting your new system. One of my favorites is <a href="https://github.com/kneath/kss">KSS</a>, which parses comments in the code and uses them to generate a style guide. For Pantsuit, I used the node version of KSS, along with a <a href="http://htanjo.github.io/kss-node-template/">template</a> to quickly spin up a documentation site.</p>
<p>I’ve listed just a few tools below; for even more, check out the tools sections of <a href="http://styleguides.io/tools">styleguides.io</a>.</p>
<ul>
<li><a href="https://fractal.build/">Fractal</a></li>
<li><a href="http://patternlab.io">Pattern Lab</a></li>
<li><a href="https://github.com/cloudfour/drizzle">Drizzle</a></li>
<li><a href="http://fbrctr.github.io/">Fabricator</a></li>
<li><a href="http://astrum.nodividestudio.com/">Astrum</a></li>
<li><a href="http://www.catalog.style/">Catalog</a></li>
</ul>
<p>Regardless of what tool you settle on, it needs to integrate well with your current workflow.</p>
<h2>Conclusion: always be refactoring</h2>
<p>If you’re not lucky enough to be able to start a new design system from scratch, you can start small and work on a single feature or component. With each new project comes a new opportunity to flesh out a new part of the system, and another potential case study to secure buy-in and showcase its value. Make sure to carefully and thoroughly document each new portion of the system as it’s built. After a few projects, you’ll find yourself with a decent start to a design system.</p>
<p>Good luck, and happy holidays!</p>
<h3>Further reading:</h3>
<ul>
<li><a href="https://24ways.org/2017/why-design-systems-fail/">Why Design Systems Fail</a></li>
<li><a href="http://bradfrost.com/blog/post/css-architecture-for-design-systems/">CSS Architecture for Design Systems</a></li>
<li><a href="https://www.amazon.com/Refactoring-Improving-Design-Existing-Code/dp/0201485672">Refactoring: Improving the Design of Existing Code</a></li>
<li><a href="https://csswizardry.com/2016/08/refactoring-css-the-three-i-s/">Refactoring CSS: The Three I’s</a></li>
<li><a href="https://www.codesimplicity.com/post/refactoring-is-about-features/">Refactoring is About Features</a></li>
</ul>

			]]></content>
		</entry>
		<entry>
			<title>Rebuilding slack.com</title>
			<link href="/posts/rebuilding-slack-com/"/>
			<updated>2017-10-11T00:00:00Z</updated>
			<id>/posts/rebuilding-slack-com/</id>
			<content type="html"><![CDATA[
				<figure id="0j8p9janchor" class="figure">
			<a href="#0j8p9j"><img alt="" loading="lazy" decoding="async" src="/assets/images/yXEcpjRdzJ-2000.jpeg" width="2000" height="1142" /></a>
			<a href="#0j8p9janchor" class="lightbox" id="0j8p9j"><span style="background-image: url('/assets/images/slack/1N48fpqutpCqswRistXpymw.jpeg')"></span></a>
			<figcaption>Illustrations by [Alice Lee](http://byalicelee.com/).</figcaption>
			</figure>
<p>In August, we released a major redesign of <a href="https://slack.com/">slack.com</a>, and we want to give you a peek behind-the-scenes. Rebuilding our marketing website was a massive project that took careful coordination across a variety of teams, departments, and agencies.</p>
<p>We implemented a redesign while overhauling all the under-the-hood code. Our aim was to address a few goals at the same time: deliver a consistent rebranded experience while tackling critical improvements to site architecture, code modularity, and overall performance and accessibility. This would afford us a new foundation for several important company initiatives, including <a href="https://slackhq.com/bienvenue-willkommen-bienvenidos-to-a-more-globally-accessible-slack-546a458b21ae">internationalization</a>.</p>
<figure id="u1zoyanchor" class="figure">
			<a href="#u1zoy"><img alt="" loading="lazy" decoding="async" src="/assets/images/_5JncT4oLm-800.png" width="800" height="538" /></a>
			<a href="#u1zoyanchor" class="lightbox" id="u1zoy"><span style="background-image: url('/assets/images/slack/1Q0gC53oTuet-cjsfhRafUQ.png')"></span></a>
<p></p></figure><p></p>
<figure id="pkfhxanchor" class="figure">
			<a href="#pkfhx"><img alt="" loading="lazy" decoding="async" src="/assets/images/SJc0oiAfn--800.png" width="800" height="593" /></a>
			<a href="#pkfhxanchor" class="lightbox" id="pkfhx"><span style="background-image: url('/assets/images/slack/1HrvfG0uHQYUc0j763Cp4uw.png')"></span></a>
<p></p></figure><p></p>
<figure id="vs1d9fanchor" class="figure">
			<a href="#vs1d9f"><img alt="" loading="lazy" decoding="async" src="/assets/images/WFr2nU_cMr-800.png" width="800" height="594" /></a>
			<a href="#vs1d9fanchor" class="lightbox" id="vs1d9f"><span style="background-image: url('/assets/images/slack/15BjTaWrvqZPjbhDrS5FBOQ.png')"></span></a>
			<figcaption>_Slack.com (L-R: August 2013, January 2017, August 2017)_</figcaption>
			</figure>
<h3>Cleaner and leaner code</h3>
<p>The old slack.com shared many code and asset dependencies with our web-based Slack client. One of our earliest goals was to decouple the website from the “web app” in order to streamline and simplify our codebase. By including only what we need to run slack.com, we are able to increase site stability, reduce developer confusion and create a codebase that is easier to iterate on. A fundamental part of this effort was the creation of our new UI framework, called :spacesuit: <strong>👩🏾‍🚀</strong>.</p>
<p>The :spacesuit: framework consists of class-based, reusable components and utility classes used to standardize our marketing pages. It allowed us to reduce our CSS payload, in one case by nearly 70% (from 416kB to 132kB).</p>
<p>Some other interesting data points:</p>
<ul>
<li>799 unique declarations, down from 1,881</li>
<li>14 unique colors, down from 91</li>
<li>1,719 selectors, down from 2,328</li>
</ul>
<figure id="edsukanchor" class="figure">
			<a href="#edsuk"><img alt="" loading="lazy" decoding="async" src="/assets/images/lVGTTLXoZh-1171.png" width="1171" height="337" /></a>
			<a href="#edsukanchor" class="lightbox" id="edsuk"><span style="background-image: url('/assets/images/slack/0Kx8ltSgpKXyXRdaD.jpg')"></span></a>
			<figcaption>**_Before_**_: Lots of deep spikes and valleys indicate poorly managed_ [_CSS specificity_](https://csswizardry.com/2014/10/the-specificity-graph/)_._</figcaption>
			</figure>
<figure id="dol6hanchor" class="figure">
			<a href="#dol6h"><img alt="" loading="lazy" decoding="async" src="/assets/images/V4L0tEaALP-1165.png" width="1165" height="335" /></a>
			<a href="#dol6hanchor" class="lightbox" id="dol6h"><span style="background-image: url('/assets/images/slack/0BmFqbD-18McrbaDi.jpg')"></span></a>
			<figcaption>**_After_**_: Using a mostly class-based system resulted in a drop in our specificity._</figcaption>
			</figure>
<p>Our CSS is organized based on the <a href="http://www.creativebloq.com/web-design/manage-large-css-projects-itcss-101517528">ITCSS philosophy</a> and uses <a href="https://csswizardry.com/2015/08/bemit-taking-the-bem-naming-convention-a-step-further/">BEM-like</a> naming conventions. Selectors are named using a single-letter prefix to indicate the type of style the class represents. The prefix is followed by the name of the component and any variation applied to it. For example, <code>u-margin-top--small</code> represents a utility class that sets <code>margin-top</code> to the small value set by our variables. Utility classes such as these are an essential part of our system as it allows our devs to fine tune pieces of UI without having to rewrite a lot of CSS. In addition, spacing between components is one of the tricker parts of creating a design system. Utility classes such as <code>u-margin-top--small</code> let us create consistent spacing and eliminate the need to reset or undo any spacing already applied to a component.</p>
<figure id="326b9ganchor" class="figure">
			<a href="#326b9g"><video autoplay="" loop="" muted="" playsinline="">
		<source src="/assets/images/slack/0_YrT_q3rSjUFssyYy.webm" type="video/webm" />
		<source src="/assets/images/slack/0_YrT_q3rSjUFssyYy.mp4" type="video/mp4" />
	</video></a>
			<a href="#326b9ganchor" class="lightbox" id="326b9g"><span style="background-image: url('/assets/images/slack/0_YrT_q3rSjUFssyYy.gif')"></span></a>
			<figcaption>_Our biggest gains were on the pricing page, which saw a 53% decrease in loading time._</figcaption>
			</figure>
<h3>A modern, responsive layout</h3>
<p>The new site uses a combination of Flexbox and CSS Grid to create responsive layouts. We wanted to utilize the latest CSS features, while also ensuring that visitors with older browsers received a comparable experience.</p>
<p>At first we tried to implement our layout with a traditional 12-column grid using CSS Grid. That approach ultimately didn’t work because we were limiting ourselves into a using a single dimensional layout when Grid is meant for two. In the end, we discovered that a column-based grid <a href="https://rachelandrew.co.uk/archives/2017/07/01/you-do-not-need-a-css-grid-based-grid-system/">wasn’t actually needed</a>. Since Grid allows you to create a custom grid to match whatever layout you have, we didn’t need to force it into 12 columns. Instead, we created CSS Grid objects for some of the common layout patterns in the designs.</p>
<p>Some of the patterns were pretty simple.</p>
<figure id="4ctc4anchor" class="figure">
			<a href="#4ctc4"><img alt="" loading="lazy" decoding="async" src="/assets/images/-YKQYeVTq8-1600.png" width="1600" height="407" /></a>
			<a href="#4ctc4anchor" class="lightbox" id="4ctc4"><span style="background-image: url('/assets/images/slack/0IXMPtmw5vQfr-fZ0.jpg')"></span></a>
			<figcaption>_A basic three-column grid block._</figcaption>
			</figure>
<p>Others were more complex, which really showcased Grid’s abilities.</p>
<figure id="yvk2nanchor" class="figure">
			<a href="#yvk2n"><img alt="" loading="lazy" decoding="async" src="/assets/images/hAXxkH744m-1600.png" width="1600" height="1107" /></a>
			<a href="#yvk2nanchor" class="lightbox" id="yvk2n"><span style="background-image: url('/assets/images/slack/0Q_tqzOLre__HPLIL.jpg')"></span></a>
			<figcaption>_A photo collage object._</figcaption>
			</figure>
<p>Before our Grid implementation, a layout like the one above required lots of wrapping, and sometimes empty, divs to mimic a two-dimensional grid.</p>
<pre class="language-html" tabindex="0" data-language="html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>section</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span>”o-section”</span><span class="token punctuation">></span></span><br />    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span>”o-content-container”</span><span class="token punctuation">></span></span><br />        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span>”o-row”</span><span class="token punctuation">></span></span><br />            &lt;div class=”col-8">…<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><br />            &lt;div class=”col-4">…<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><br />        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><br />        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span>”o-row”</span><span class="token punctuation">></span></span><br />            &lt;div class=”col-1"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><br />            &lt;div class=”col-3">…<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><br />            &lt;div class=”col-8">…<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><br />        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><br />    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><br /><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>section</span><span class="token punctuation">></span></span></code></pre>
<p>With CSS Grid, we’re able to remove the extra markup needed to simulate a grid, and simply create one natively. Starting with Grid lets us use less markup, in addition to making sure the markup we use is semantic.</p>
<pre class="language-html" tabindex="0" data-language="html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>section</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span>”c-photo-collage</span> <span class="token attr-name">c-photo-collage--three”</span><span class="token punctuation">></span></span><br />    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>img</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span>”example-1.jpg”</span> <span class="token attr-name">alt</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span>””</span><span class="token punctuation">></span></span><br />    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>img</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span>”example-2.jpg”</span> <span class="token attr-name">alt</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span>””</span><span class="token punctuation">></span></span><br />    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>blockquote</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span>”c-quote”</span><span class="token punctuation">></span></span><br />        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span>”c-quote\_\_text”</span><span class="token punctuation">></span></span>…<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">></span></span><br />    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>blockquote</span><span class="token punctuation">></span></span><br />    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>img</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span>”example-3.jpg”</span> <span class="token attr-name">alt</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span>””</span><span class="token punctuation">></span></span><br /><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>section</span><span class="token punctuation">></span></span></code></pre>
<p>At first we used Modernizr to detect Grid support, however that resulted in flashes of unstyled layout while the library loaded.</p>
<figure id="xf08hanchor" class="figure">
			<a href="#xf08h"><video autoplay="" loop="" muted="" playsinline="">
		<source src="/assets/images/slack/0_PFKwdHYeunJfV-Sh.webm" type="video/webm" />
		<source src="/assets/images/slack/0_PFKwdHYeunJfV-Sh.mp4" type="video/mp4" />
	</video></a>
			<a href="#xf08hanchor" class="lightbox" id="xf08h"><span style="background-image: url('/assets/images/slack/0_PFKwdHYeunJfV-Sh.gif')"></span></a>
			<figcaption>_Pages defaulted to the mobile layout and reflowed once Modernizr detected Grid support._</figcaption>
			</figure>
<p>We decided that addressing the jarring experience of the layout shift was a higher priority than backwards compatibility. The compromise was to use CSS Grid as an enhancement and fallback to Flexbox and other techniques when needed.</p>
<p>Instead of using a library to detect Grid support, we went with CSS feature queries. Unfortunately, feature queries aren’t supported in every browser. This means that any browser that can’t handle the <code>@supports</code> rule will not get the CSS Grid layout, even if that browser supports Grid. So IE11, for example, will always use our Flexbox-based layout even though it supports some Grid features.</p>
<p>We use some features of Grid that aren’t currently fully supported in all browsers, the most notable being percentage-based <code>grid-gap</code>. Although support for this has been implemented in some versions of Safari, we still needed to anticipate its absence. In practice, a Grid object is styled as follows:</p>
<pre class="language-css" tabindex="0" data-language="css"><code class="language-css"><span class="token atrule"><span class="token rule">@supports</span> <span class="token punctuation">(</span><span class="token property">display</span><span class="token punctuation">:</span> grid<span class="token punctuation">)</span> <span class="token keyword">and</span> <span class="token punctuation">(</span><span class="token property">grid-template-columns</span><span class="token punctuation">:</span> <span class="token function">repeat</span><span class="token punctuation">(</span>3<span class="token punctuation">,</span> 1fr<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">and</span> <span class="token punctuation">(</span><span class="token property">grid-row-gap</span><span class="token punctuation">:</span> 1%<span class="token punctuation">)</span> <span class="token keyword">and</span> <span class="token punctuation">(</span><span class="token property">grid-gap</span><span class="token punctuation">:</span> 1%<span class="token punctuation">)</span> <span class="token keyword">and</span> <span class="token punctuation">(</span><span class="token property">grid-column-gap</span><span class="token punctuation">:</span> 1%<span class="token punctuation">)</span></span> <span class="token punctuation">{</span><br /><br />    <span class="token selector">.c-photo-collage</span> <span class="token punctuation">{</span><br />        <span class="token property">display</span><span class="token punctuation">:</span> grid<span class="token punctuation">;</span><br />        <span class="token property">grid-gap</span><span class="token punctuation">:</span> 1.5rem 2.4390244%<span class="token punctuation">;</span><br />    <span class="token punctuation">}</span><br /><br />    <span class="token selector">.c-photo-collage > :nth-child(1)</span> <span class="token punctuation">{</span><br />        <span class="token property">grid-column</span><span class="token punctuation">:</span> 1 / span 3<span class="token punctuation">;</span><br />        <span class="token property">grid-row</span><span class="token punctuation">:</span> 1<span class="token punctuation">;</span><br />    <span class="token punctuation">}</span><br /><br />    <span class="token selector">.c-photo-collage > :nth-child(2)</span> <span class="token punctuation">{</span><br />        <span class="token property">grid-column</span><span class="token punctuation">:</span> 2<span class="token punctuation">;</span><br />        <span class="token property">grid-row</span><span class="token punctuation">:</span> 2<span class="token punctuation">;</span><br />    <span class="token punctuation">}</span><br /><br />    <span class="token selector">.c-photo-collage > :nth-child(3)</span> <span class="token punctuation">{</span><br />        <span class="token property">grid-column</span><span class="token punctuation">:</span> 4<span class="token punctuation">;</span><br />        <span class="token property">grid-row</span><span class="token punctuation">:</span> 1<span class="token punctuation">;</span><br />        <span class="token property">align-self</span><span class="token punctuation">:</span> flex-end<span class="token punctuation">;</span><br />    <span class="token punctuation">}</span><br /><br />    <span class="token selector">.c-photo-collage > :nth-child(4)</span> <span class="token punctuation">{</span><br />        <span class="token property">grid-column</span><span class="token punctuation">:</span> 3 / span 2<span class="token punctuation">;</span><br />        <span class="token property">grid-row</span><span class="token punctuation">:</span> 2 / span 2<span class="token punctuation">;</span><br />    <span class="token punctuation">}</span><br /><br /><span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre>
<p>Any browser that doesn’t meet the query requirements will use our flexbox fallbacks instead.</p>
<pre class="language-css" tabindex="0" data-language="css"><code class="language-css"><span class="token atrule"><span class="token rule">@supports</span> <span class="token keyword">not</span> <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token property">display</span><span class="token punctuation">:</span> grid<span class="token punctuation">)</span> <span class="token keyword">and</span> <span class="token punctuation">(</span><span class="token property">grid-column-gap</span><span class="token punctuation">:</span> 1%<span class="token punctuation">)</span><span class="token punctuation">)</span></span> <span class="token punctuation">{</span><br />    /\* fabulously written CSS goes here \*/<br /><span class="token punctuation">}</span></code></pre>
<h3>Fluid typesetting</h3>
<p>Once we had responsive layouts, we needed equally adaptable typography. We created <a href="http://lesscss.org/features/#mixins-feature">Less mixins</a> to help us fine-tune our typesetting. Typeset is a mixin that acts as single source of truth for all typography settings. For each type style, a new line is created inside the mixin that contains the name or purpose of the style, followed by a list of settings for each style. They are, in order: <code>font-family</code>, min and max <code>font-size</code> (in rems by default), <code>line-height</code>, <code>font-weight</code>, and any <code>text-transforms</code>, such as <code>uppercase</code>. For clarity, each type name is prefixed with <code>display-as-</code> to make its purpose plain.</p>
<p>Here’s a simplified version of the mixin:</p>
<pre class="language-less" tabindex="0" data-language="less"><code class="language-less"><span class="token selector">.m-typeset(<span class="token variable">@setting</span>)</span> <span class="token punctuation">{</span><br />    <span class="token variable">@display-as-h1<span class="token punctuation">:</span></span> <span class="token variable">@font-family-serif</span><span class="token punctuation">,</span> 2<span class="token punctuation">,</span> 2.75<span class="token punctuation">,</span> 1.1<span class="token punctuation">,</span> <span class="token variable">@font-semibold</span><span class="token punctuation">;</span><br />    <span class="token variable">@display-as-btn-text<span class="token punctuation">:</span></span> <span class="token variable">@font-family-sans</span><span class="token punctuation">,</span> .9<span class="token punctuation">,</span> .875<span class="token punctuation">,</span> 1.3<span class="token punctuation">,</span> <span class="token variable">@font-bold</span><span class="token punctuation">,</span> ~”uppercase”<span class="token punctuation">;</span><br />    <span class="token property">font-family</span><span class="token punctuation">:</span> <span class="token function">extract</span><span class="token punctuation">(</span><span class="token variable">@@setting</span><span class="token punctuation">,</span> 1<span class="token punctuation">)</span><span class="token punctuation">;</span><br />    <span class="token property">font-weight</span><span class="token punctuation">:</span> <span class="token function">extract</span><span class="token punctuation">(</span><span class="token variable">@@setting</span><span class="token punctuation">,</span> 5<span class="token punctuation">)</span><span class="token punctuation">;</span><br />    <span class="token property">line-height</span><span class="token punctuation">:</span> <span class="token function">extract</span><span class="token punctuation">(</span><span class="token variable">@@setting</span><span class="token punctuation">,</span> 4<span class="token punctuation">)</span><span class="token punctuation">;</span><br /><span class="token punctuation">}</span></code></pre>
<p>See it in action:</p>
<pre class="language-less" tabindex="0" data-language="less"><code class="language-less"><span class="token selector">.c-button</span> <span class="token punctuation">{</span> <span class="token mixin-usage function">.m-typeset</span><span class="token punctuation">(</span>“display<span class="token operator">-</span>as<span class="token operator">-</span>btn<span class="token operator">-</span>text”<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre>
<p>The logic for this mixin takes a parameter, such as <code>display-as-btn-text</code>, and extracts the settings from the list at the index indicated for each property. In this example, the <code>line-height</code> property would be set to 1.3 because it is the 4th indexed value. The resulting CSS would be</p>
<pre class="language-css" tabindex="0" data-language="css"><code class="language-css"><span class="token selector">.c-button</span> <span class="token punctuation">{</span><br />    <span class="token property">font-family</span><span class="token punctuation">:</span> ‘Slack-Averta’<span class="token punctuation">,</span> sans-serif<span class="token punctuation">;</span><br />    <span class="token property">font-weight</span><span class="token punctuation">:</span> 700<span class="token punctuation">;</span><br />    <span class="token property">line-height</span><span class="token punctuation">:</span> 1.3<span class="token punctuation">;</span><br />    <span class="token property">text-transform</span><span class="token punctuation">:</span> uppercase<span class="token punctuation">;</span><br /><span class="token punctuation">}</span></code></pre>
<h3>Art direction &amp; imagery</h3>
<p><a href="http://byalicelee.com/">Alice Lee</a> provided us with some beautiful illustrations, and we wanted to make sure we showcased them in the best possible light. Sometimes it was necessary to display a different version of an image depending upon the viewport width. We toggled between retina vs. non-retina assets, and made image adjustments for specific screen widths.</p>
<p>This process, also known as <a href="http://usecases.responsiveimages.org/#art-direction">art direction</a>, is accomplished by using the <a href="https://html.spec.whatwg.org/multipage/embedded-content.html#embedded-content"><code>picture</code> and <code>source</code></a> elements with <a href="https://scottjehl.github.io/picturefill/">Picturefill</a> as a polyfill for older browsers. Defining characteristics, like device size, device resolution, orientation allows us to display different image assets when the design dictates it.</p>
<figure id="0z9xnanchor" class="figure">
			<a href="#0z9xn"><video autoplay="" loop="" muted="" playsinline="">
		<source src="/assets/images/slack/15SzojYwz0QGQF614iNNBmg.webm" type="video/webm" />
		<source src="/assets/images/slack/15SzojYwz0QGQF614iNNBmg.mp4" type="video/mp4" />
	</video></a>
			<a href="#0z9xnanchor" class="lightbox" id="0z9xn"><span style="background-image: url('/assets/images/slack/15SzojYwz0QGQF614iNNBmg.gif')"></span></a>
			<figcaption>_Our Features pages use_ srcset _to display different images based on viewport size._</figcaption>
			</figure>
<p>With these tools, we were able to display the best possible version of an asset based upon query parameters we set. In the above example, the main hero image needed a simpler version for a smaller viewport.</p>
<pre class="language-html" tabindex="0" data-language="html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>picture</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span>”o-section_illustration</span> <span class="token attr-name">for-desktop-only”</span><span class="token punctuation">></span></span><br />    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>source</span> <span class="token attr-name">srcset</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span>”/img/features/information/desktop/hero.png”</span> <span class="token attr-name">sizes</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span>”1x,</span> <span class="token attr-name">2x”</span> <span class="token attr-name">media</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span>”(min-width:</span> <span class="token attr-name">1024px)”</span> <span class="token attr-name">alt</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span>””</span><span class="token punctuation">></span></span><br />    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>img</span> <span class="token attr-name">srcset</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span>”/img/features/information/mobile/hero.png”</span> <span class="token attr-name">sizes</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span>”1x,</span> <span class="token attr-name">2x”</span> <span class="token attr-name">alt</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span>””</span><span class="token punctuation">></span></span><br /><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>picture</span><span class="token punctuation">></span></span></code></pre>
<p>This technique allows us to specify which image asset is shown for a particular media query, plus if retina and non-retina assets are needed and available. The end result is greater art direction throughout the site.</p>
<h3>Inclusive, from the start</h3>
<p>Another major goal was to ensure that low-vision, screenreader and keyboard-only users could navigate the site with ease. While starting from a clean codebase, we were able to make many impactful improvements to color contrast, semantic HTML and keyboard accessibility with little additional effort. Additionally, we were able to work in some new features for a more accessible experience. We added a <a href="https://webaim.org/techniques/skipnav/">skip link</a> before the navigation so that users could bypass the menu if desired. For a better screenreader experience, we added an <a href="https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Live_Regions">aria-live region</a> and helper functions to announce form errors and route changes. In addition, interactions are keyboard accessible with noticeable focus states. We also strived to use clear, descriptive alt text.</p>
<h3>Looking Forward</h3>
<p>There are always more wins to be had for better performance, maintainability and accessibility. We are refining our site telemetry to better understand where the bottlenecks lie and where we can make the most impact. We’re proud of the progress we have made; progress that will surely serve us well as we look to create a more pleasant experience for our customers around the world.</p>

			]]></content>
		</entry>
		<entry>
			<title>Pantsuit: The Hillary Clinton UI pattern library</title>
			<link href="/posts/pantsuit-the-hillary-clinton-ui-pattern-library/"/>
			<updated>2016-09-01T01:43:53Z</updated>
			<id>/posts/pantsuit-the-hillary-clinton-ui-pattern-library/</id>
			<content type="html"><![CDATA[
				<figure id="haa76anchor" class="figure">
			<a href="#haa76"><img alt="" loading="lazy" decoding="async" src="/assets/images/LY8vQ_KXCc-1600.jpeg" width="1600" height="1200" /></a>
			<a href="#haa76anchor" class="lightbox" id="haa76"><span style="background-image: url('/assets/images/pantsuit/15C5u2qaG6obSqqnVugc-Aw.jpeg')"></span></a>
			<figcaption>Every good Pantsuit starts with the right patterns.</figcaption>
			</figure>
<p>Design systems. Pattern libraries. Styleguides. Whatever you want to call them, they are very much in style right now.</p>
<p>A design system’s purpose is to provide consistent, tested and reusable solutions for a common UX problem.</p>
<p>Campaigns move at <a href="https://medium.com/git-out-the-vote/building-applications-at-campaign-speed-281e802360c2#.u789ixvnz">lightning speed</a>, and have some hard, <a href="https://days.to/election-day-in-us/2016">non-negotiable deadlines</a>. To empower our developers to create and ship products at the pace our needs require while maintaining a consistent UI, a single, unified design system was needed.</p>
<p>Thus, Pantsuit was born.</p>
<figure id="tghd7anchor" class="figure">
			<a href="#tghd7"><video autoplay="" loop="" muted="" playsinline="">
		<source src="/assets/images/pantsuit/169FyZhDZJcclYYK42AvGvw.webm" type="video/webm" />
		<source src="/assets/images/pantsuit/169FyZhDZJcclYYK42AvGvw.mp4" type="video/mp4" />
	</video></a>
			<a href="#tghd7anchor" class="lightbox" id="tghd7"><span style="background-image: url('/assets/images/pantsuit/169FyZhDZJcclYYK42AvGvw.gif')"></span></a>
			<figcaption>Me, deciding on the name “Pantsuit”</figcaption>
			</figure>
<p>Pantsuit is Hillary for America’s internal design system. Its primary goal is to serve as a single source of truth for the design and front-end teams. My job is to make sure the system is modular and flexible enough to be used in any number of unpredictable ways.</p>
<figure id="frkd5anchor" class="figure">
			<a href="#frkd5"><img alt="" loading="lazy" decoding="async" src="/assets/images/2aMoh5yxZa-2000.jpeg" width="2000" height="596" /></a>
			<a href="#frkd5anchor" class="lightbox" id="frkd5"><span style="background-image: url('/assets/images/pantsuit/18dr4NXH-n1TlB4WBw4BUpg.jpeg')"></span></a>
			<figcaption>_Our_ [_phone banking tool_](https://www.hillaryclinton.com/calls/) _and_ [_The Briefing_](https://www.hillaryclinton.com/briefing/) _are two projects utilizing Pantsuit._</figcaption>
			</figure>
<p>The first version of the system was created for, and is still used by, our donations platform. Its purpose was to achieve a 1:1 UI parity of the live site while completely rewriting the underlying code base.</p>
<p>When the time came for a redesign of <a href="http://www.hillaryclinton.com">hillaryclinton.com</a>, I was charged with creating a new version of Pantsuit while simultaneously building the new site.</p>
<figure id="m1i2nhanchor" class="figure">
			<a href="#m1i2nh"><img alt="" loading="lazy" decoding="async" src="/assets/images/9U0EtVfgPq-1267.png" width="1267" height="938" /></a>
			<a href="#m1i2nhanchor" class="lightbox" id="m1i2nh"><span style="background-image: url('/assets/images/pantsuit/1cAm7KUh3P6lFfZaKjxzi8Q.png')"></span></a>
			<figcaption>_Mama’s got a brand new Pantsuit._</figcaption>
			</figure>
<p>This system isn’t perfect, and is by no means dogmatic. It’s simply what has worked for us given the pace and scope of the work we do.</p>
<h3>Modular architecture</h3>
<p>The core CSS architecture of Pantsuit is based around a combination of <a href="http://smacss.com">SMACSS</a> and Harry Roberts’ <a href="http://www.creativebloq.com/web-design/manage-large-scale-web-projects-new-css-architecture-itcss-41514731">ITCSS</a>, along with his brilliant <a href="http://csswizardry.com/2015/03/more-transparent-ui-code-with-namespaces/">namespacing</a> patterns.</p>
<p>Each class name is prefixed with an indicator of that class’ purpose and scope, based on the ITCSS inverted triangle.</p>
<figure id="u6o7fkanchor" class="figure">
			<a href="#u6o7fk"><img alt="" loading="lazy" decoding="async" src="/assets/images/RD4NActn_Z-1440.jpeg" width="1440" height="691" /></a>
			<a href="#u6o7fkanchor" class="lightbox" id="u6o7fk"><span style="background-image: url('/assets/images/pantsuit/1K0X161jn_6wTKjuTLjN_TQ.jpeg')"></span></a>
			<figcaption>_It’s an inverted hanger. Cause Pantsuit. Get it?_</figcaption>
			</figure>
<pre class="language-scss" tabindex="0" data-language="scss"><code class="language-scss">.o- <span class="token comment">// an object, an unstyled design pattern</span><br />.c- <span class="token comment">// a component, a styled piece of UI</span><br />.a- <span class="token comment">// an alteration, an UI-independent override</span><br />.t- <span class="token comment">// a theme, change UI appearance based on theme</span><br />.is-<span class="token punctuation">,</span> .has-<span class="token punctuation">,</span> .for- <span class="token comment">// state-based styles</span><br />.js- <span class="token comment">// used for binding behavior to components</span></code></pre>
<p>In each layer of the inverted triangle, the scope of the styles get narrower and more specific. At the bottom of this is a layer of utility or helper classes, referred to as “trumps”, that contains high-specificity selectors. We use these selectors to make very targeted alterations to existing components, and shouldn’t be overridden. As such, they often use !important to ensure the desired alteration is achieved, such as .u-no-margin { margin: 0 !important; }. However, <a href="https://www.hillaryclinton.com/feed/how-many-ways-can-the-nations-newspapers-declare-donald-trump-unfit-to-be-commander-in-chief/">for</a> <a href="https://www.hillaryclinton.com/feed/5-questions-every-voter-should-ask-about-donald-trumps-bizarre-relationship-with-russia/">obvious</a> <a href="https://www.hillaryclinton.com/feed/theres-a-reason-why-white-supremacists-like-donald-trump/">reasons</a>, I refuse to call them “trump” classes. Instead, I refer to these classes as “alterations.” So .u-no-margin becomes .a-no-margin.</p>
<p>Aside from some high-level styling on HTML elements, our system consists of these type of class-based selectors. This markup-independent approach allowed us to solve an unique problem. In particular, it gave us the tools to style the same collection of components with the same markup, differently based on its position in the DOM.</p>
<figure id="2i5jsanchor" class="figure">
			<a href="#2i5js"><img alt="" loading="lazy" decoding="async" src="/assets/images/_dupeleWq6-2000.jpeg" width="2000" height="800" /></a>
			<a href="#2i5jsanchor" class="lightbox" id="2i5js"><span style="background-image: url('/assets/images/pantsuit/1dfop6AVxjPQx9bzA8rAPGQ.jpeg')"></span></a>
			<figcaption>_We really love forms. Also, have you_ [_signed up to get texts_](https://www.hillaryclinton.com/forms/texts-from-hillary/)_?_</figcaption>
			</figure>
<p>For example, each of these call-to-action forms have the similar markup, with the main difference being their location on the page. The styling and layout of the form elements change based on the container the form is placed in. This is in addition to some base-level styling on the inputs and buttons to achieve consistency.</p>
<h3>A more inclusive system</h3>
<p>From the beginning, creating an inclusive experience was a purposeful goal of both the new website, and the new design system. Our primary focus was to be WCAG 2.0 AA compliant in terms of keyboard accessibility and color contrast, and to use accurately semantic HTML.</p>
<p>One easy step towards achieving compliance was to ensure that the content of each page was in logical order. With that in mind, I made the decision to decouple the sizing of headings from the elements. This means that h1, h2, etc, have no sizing associated with them. Instead, the typographic scale is scoped to classes such as .c-headline-alpha. This ensures that headings are used for semantic, hierarchical purposes and not to achieve a specific font size. Using the correct HTML elements alone addressed a large portion of our accessibility needs.</p>
<p>To make sure that color-blind and low-vision users could easily see our content, the design team made some adjustments to our initial color palette to provide better contrast between background and text elements.</p>
<figure id="szuffanchor" class="figure">
			<a href="#szuff"><img alt="" loading="lazy" decoding="async" src="/assets/images/6FG7gq4m8x-2000.jpeg" width="2000" height="624" /></a>
			<a href="#szuffanchor" class="lightbox" id="szuff"><span style="background-image: url('/assets/images/pantsuit/1RngcpTaRJE9jenUA2lMsZg.jpeg')"></span></a>
			<figcaption>_Homepage elements before and after color contrast fixes._</figcaption>
			</figure>
<p>In addition to proper use of hierarchy and contrast, we implemented separate focus states from hover states to provide keyboard-only users the visual feedback they need when navigating a page.</p>
<p>Of course there’s still work to be done, but the <a href="https://www.lullabot.com/articles/auditing-presidential-websites-for-accessibility">initial feedback</a> has been positive.</p>
<h3>Documentation</h3>
<p>A design system is only as good as its documentation, so it was really important that I created a site that was both easy for my team to use and for me to keep updated. We use a combination of <a href="https://github.com/assemble/assemble">assemble</a>, <a href="https://github.com/kss-node/kss-node">kss-node</a> and <a href="https://github.com/mozilla/nunjucks">nunjucks</a> to document Pantsuit.</p>
<figure id="zweraanchor" class="figure">
			<a href="#zwera"><img alt="" loading="lazy" decoding="async" src="/assets/images/-FZqXML3SB-1600.png" width="1600" height="820" /></a>
			<a href="#zweraanchor" class="lightbox" id="zwera"><span style="background-image: url('/assets/images/pantsuit/1w7G52xHHslBw7tJLUj1Vcg.png')"></span></a>
<p></p></figure><p></p>
<p>KSS-node parses the comments in the code and generates markup based on the actual styles of your system. As the styles are updated, so is the documentation.</p>
<pre class="language-scss" tabindex="0" data-language="scss"><code class="language-scss"><span class="token comment">// Button</span><br /><span class="token comment">// Buttons can and should be clicked. Buttons come in two sizes, small and large. To create a large button, add a class of \`c-button-large\`. To create a link that looks like a button, add the \`c-button-link\` class.</span><br /><span class="token comment">// .secondary — Use to indicate a secondary call-to-action.</span><br /><span class="token comment">// Markup:</span><br /><span class="token comment">// buttons.html</span><br /><span class="token comment">// Styleguide 5.button</span></code></pre>
<figure id="xdsi4anchor" class="figure">
			<a href="#xdsi4"><img alt="" loading="lazy" decoding="async" src="/assets/images/9hU1zhiqT9-1600.png" width="1600" height="818" /></a>
			<a href="#xdsi4anchor" class="lightbox" id="xdsi4"><span style="background-image: url('/assets/images/pantsuit/1swte0LdEuqD3kvQ9LwcyvA.png')"></span></a>
			<figcaption>_Documenting all the things!_</figcaption>
			</figure>
<hr />
<h3>What’s next?</h3>
<p>There’s less than 3 months left and we’re just getting started. There’s still time to join this crazy journey. Want to solve real problems and help elect the next President of the United States? Join our <a href="https://devprogress.us/">team of volunteers</a>.</p>

			]]></content>
		</entry></feed>