Commit ac4cd7db authored by Laura Kalbag's avatar Laura Kalbag
Browse files

Update blog post on index and include nice images

parent 41896ebd
......@@ -53,11 +53,13 @@
</ul>
</nav>
<div class='main h-entry'>
<h1 class='p-name long-title'>Overhaul to Better’s CSS</h1>
<p class='post-date dt-published' datetime='2015-11-25 11:55:00'>25th November, 2016 — <span class='p-author'>Laura Kalbag</span></p>
<h1 class='p-name long-title'>Overhauling Better’s CSS</h1>
<p class='post-date dt-published' datetime='2015-11-29 11:55:00'>29th November, 2016 — <span class='p-author'>Laura Kalbag</span></p>
<div class='e-content'>
<p>CSS is vital to Better. The Better apps (iOS and Mac) use web pages for their content. They’re the same pages you see on the Better site, but with slightly different templates allowing the apps to make appropriate use of their native technology. Still, the content you see on the apps is largely HTML and CSS. The pre-compiled architecture is fairly straight-forward:</p>
<p>CSS is vital to <a href="https://better.fyi">Better</a>. The Better apps (<a href="https://itunes.apple.com/us/app/better-by-ind.ie/id1080964978?ls=1&mt=8">iOS</a> and <a href="https://itunes.apple.com/us/app/better/id1121192229?ls=1&mt=12">Mac</a>) use web pages for their content. They’re the same pages you see on the <a href="https://better.fyi">Better site</a>, but with slightly different templates allowing the apps to make appropriate use of their native technology. Still, the content you see on the apps is largely HTML and CSS.</p>
<p>The pre-compiled architecture is fairly straight-forward:</p>
<ul>
<li>a common CSS file for styles that cover both the site and the apps</li>
......@@ -65,31 +67,35 @@
<li>an app CSS file that covers rendering differences between the app(s) and site</li>
</ul>
<p>All the CSS is compiled into a global CSS file during the build process using the common CSS, and either the app or site CSS depending on its destination.</p>
<p>Each of the CSS files is compiled into a global CSS file during the build process using first the common CSS file, and then either the app or site CSS files.</p>
<h2>The opportunity</h2>
<p>When we first launched Better, the iOS app had a coloured frame around the content. The frame was in the native app, and meant the content viewport size was slightly different than viewing the same content on the site in a web browser on the same device. It also meant the CSS required specific media queries to ensure more complex design elements, such as the statistics, would fit the viewport and still look good on narrow devices.</p>
<p>When we first launched Better, the iOS app had a coloured frame around the content (see below). The frame was in the native app, and meant the content viewport size was slightly different than viewing the same content on the site in a web browser on the same device. It also meant the CSS required specific media queries to ensure more complex design elements, such as the statistics, would fit the viewport and still look good on narrow devices.</p>
<p> <a href="">image of old and new app layouts side-by-side</a></p>
<figure>
<img src="images/border-to-borderless.jpg" alt="Two screenshots of the statistics on the Cloud of Shame on iPhone 6" width="750" height="667" style="margin-left:auto;margin-right:auto;height:auto;border:1px #ccc solid;">
<figcaption>
<p>Left: the app with the coloured frame, right: the app without the coloured frame.</p>
</figcaption>
</figure>
<p>In September, Aral removed the coloured frame from the app interface. Firstly this gave the interface a much cleaner and spacious feel, but it also meant the viewport widths were exactly the same whether you were looking at Better content in the app or in a web browser. This gave me the opportunity to overhaul the CSS, removing excess rules and repetition mostly caused by a gazillion media queries.</p>
<p>Skip to the CSSing.</p>
<p>In September, Aral removed the coloured frame from the app interface. Firstly this gave the interface a much cleaner and more spacious feel, but it also meant the viewport widths were exactly the same whether you were looking at Better content in the app or in a web browser on the same device. This gave me the opportunity to overhaul the CSS, removing excess rules and repetition mostly caused by a gazillion media queries.</p>
<h2>Changing the way I design for the web</h2>
<p>In a yet-to-be-releasable redesign of my own site, I’d started experimenting with a new approach to units and measurements in my design and overall CSS. I started using <code>em</code>s for everything. Using <code>em</code>s turned out to be easy, and made my CSS clean and simple, especially as I was writing the CSS from scratch. Using <code>em</code>s isn’t new or revelatory in the web world. But it was always an approach I shied away from before.</p>
<p>In a yet-to-be-releasable redesign of <a href="https://laurakalbag.com">my own site</a>, I’d started experimenting with a new approach to units and measurements in my design and overall CSS. I started using <code>em</code>s for every unit. Using <code>em</code>s turned out to be easy, and made my CSS clean and simple, especially as I was writing the CSS from scratch. Using <code>em</code>s isn’t new or revelatory in the web world. But it was always an approach I shied away from before.</p>
<p>I’m pretty good at CSS. You don’t get away with being this bad at JavaScript without knowing CSS very well (and being modest.) Still, it’s taken me a long time to relinquish control over the pixel precision-based thinking learned through years of designing in bitmap graphic software. One can take the Photoshop away from the woman, but you can’t take the Photoshop mindset out of the woman. Even though I hadn’t designed in Photoshop in nearly a decade, had used vector graphic software, had jumped on responsive web design as soon as I heard about it, my brain still thought, and designed, in pixels. When I read anything new about responsive design and other development approaches, I took them on board, but I still envisioned my work as pixels mapped in the canvas space. I used <code>rem</code>s and media queries, but these were usually compiled from pixel units. I abstracted away my inflexible pixel brain.</p>
<p>I’m pretty good at CSS. You don’t get away with being this bad at JavaScript without knowing CSS very well. Still, it’s taken me a long time to relinquish control over the pixel precision-based thinking learned through years of designing in bitmap graphic software. One can take the Photoshop away from the woman, but you can’t take the Photoshop mindset out of the woman. Even though I hadn’t designed in Photoshop in nearly a decade, had used vector graphic software, had jumped on responsive web design as soon as I heard about it, my brain still thought, and designed, in pixels. When I read anything new about responsive design and other development approaches, I used those techniques, but I still envisioned my work as pixels mapped in the canvas space. I used <code>rem</code>s and media queries, but these were usually compiled from pixel units. I abstracted away my inflexible pixel brain.</p>
<h2>To a flexible everything with <code>em</code>s</h2>
<h2>To a flexible everything with ems</h2>
<p>As Better no longer needed so many media queries, the leap from <code>rem</code>s and <code>px</code> to <code>em</code>s was straight-forward. Though from a design perspective, it was harder to visualise the units as relationships between the type and space without starting from scratch. In order to better visualise the design in flexible units, it turned into a complete refactor.</p>
<p>As Better no longer needed so many media queries, the leap from <code>rem</code>s and <code>px</code> to <code>em</code>s was straight-forward. Though from a visual perspective, it was hard to visualise the units as relationships between the type and space without starting from scratch. In order to better visualise the design in flexible units, it turned into a complete refactor.</p>
<p>I started by converting all <code>font-size</code>s to <code>em</code>s, then removing any subsequent media queries relating to those font sizes, instead using two media queries on the root:</p>
<pre><code>html
<figure><pre><code>html
{
/* ↓ root size */
font-size: 14px;
......@@ -112,15 +118,19 @@
}
}</code></pre>
<figcaption>
<p>This makes all font sizes scale up proportionally at 460px and 600px viewport widths.</p>
</figcaption>
</figure>
<p>Then I took all the paddings, margins, max-widths, and anything else related to space or layout, and converted those units to <code>em</code>s, removing their media queries too. I generally used the old <code>target/context = result</code> rule. So the <code>margin: 12px;</code> when the root <code>font-size</code> was <code>14px</code> became <code>margin: 0.857142857em;</code>. The decimals are ugly, and harder to visualise, so I rounded units to the nearest .5 or .25 as I re-factored. This makes the <code>margin: 0.857142857em;</code> a much tidier <code>margin: 0.85em;</code>.</p>
<p>Then I took all the paddings, margins, max-widths, and anything else related to space or layout, and converted those units to <code>em</code>s, removing their media queries too. I generally used <a href="https://abookapart.com/products/responsive-web-design">the old <code>target/context = result</code> rule</a>. A <code>margin: 12px;</code>, with a root <code>font-size</code> of <code>14px</code> becomes <code>margin: 0.857142857em;</code>. The decimals are ugly, and harder to visualise, so I rounded units to the nearest .5 or .25 as I re-factored. This makes the <code>margin: 0.857142857em;</code> a much tidier <code>margin: 0.85em;</code>.</p>
<p>With barely any media queries, the CSS was easier to manage. It meant I could have a fresh look at the relationships between the type and the space, adjusting consistently across all the elements. I first style based on the naked elements (<code>h1, h2… ul… p</code> etc) themselves. (<a href="https://www.smashingmagazine.com/2016/11/css-inheritance-cascade-global-scope-new-old-worst-best-friends/">Heydon recently wrote a great article on the benefits of this approach</a>.) Styling without classes is also necessary as most of our content is generated directly from markdown.</p>
<p>With barely any media queries, the CSS was easier to manage. It meant I could have a fresh look at the relationships between the type and the space, adjusting consistently across all the elements. When writing CSS, I first style based on the naked elements (<code>h1, h2… ul… p</code> etc) themselves. (<a href="https://www.smashingmagazine.com/2016/11/css-inheritance-cascade-global-scope-new-old-worst-best-friends/">Heydon recently wrote a great article on the benefits of this approach</a>.) Styling without classes is also necessary as most of our content is generated directly from markdown.</p>
<p>The few modules that rely on classes for more complex layouts and styles (such as the statistics below) didn’t need a million breakpoints either. The core typography and spacing of these modules were already adjusting to the available space derived from the base element CSS, so when refactoring, the rules only occasionally needed minor tweakpoints.</p>
<p><a href="">screenshot of statistics</a></p>
<figure>
<img src="images/statistics.png" alt="After Better statistics with icons and text flowing side-by-side" width="521" height="369" style="margin-left:auto;margin-right:auto;height:auto;border:1px #ccc solid;"></p>
<p>Once the rest of the layouts were relying on <code>em</code> units, I could make any icons (which are SVG background images) use <code>em</code>s for their sizing too. Using <code>em</code>s for SVG icons make perfect sense, as they’re vector anyway, and means they can then scale to the text around them.</p>
......@@ -131,72 +141,97 @@
<p>In the spirit of refactor, I went all-out. On the current <a href="https://better.fyi/spotlight/">Spotlight page</a>, we have a big “Bait!” headline, filling the width of the main container. It was a perfect opportunity to replace a load of media queries with <code>vw</code> units for the <code>font-size</code>. The only additional CSS needed was a media query to ensure it doesn&#39;t exceed the width of the container when the viewport is wider than the container.</p>
<pre><code>body.spotlight h1.headline
{
/* ↓ fallback */
font-size: 8em;
font-size: 36vw;
line-height: 1;
}
{
/* ↓ fallback */
font-size: 8em;
font-size: 36vw;
line-height: 1;
}
@media only screen and (min-width: 600px)
@media only screen and (min-width: 600px)
{
body.spotlight h1.headline
{
body.spotlight h1.headline
{
font-size: 13.2em;
}
}</code></pre>
font-size: 13.2em;
}
}</code></pre>
<h2>Better SVGs</h2>
<p>Getting all overexcited with stripping out unnecessary CSS, I decided to do the same with our graphics too. Last month I read <a href="https://abookapart.com/products/practical-svg">Chris Coyier’s Practical SVG</a> which helped me understand the ins-and-outs of SVG much better. To help grok as I was learning, I created a little find-and-replace script to scrub all the junk out of a generated SVG file to keep it nice and small. One of Chris’ simplest tips was removing excess decimals from the path points. This alone can halve the size of an SVG.</p>
<pre><code><?xml version="1.0" encoding="UTF-8"?>
<svg width="25px" height="28px" viewBox="0 0 25 28" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 41.1 (35376) - http://www.bohemiancoding.com/sketch -->
<title>resources-small</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Icons-and-Clouds" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="table" transform="translate(0.000000, -93.000000)" stroke="#787878">
<g id="note" transform="translate(4.000000, 99.000000)">
<polygon id="paper" stroke-linecap="round" stroke-linejoin="round" points="0.5 0.5 11.5622559 0.5 16.5 5.49975586 16.5 20.5 0.5 20.5"></polygon>
<polyline id="corner" points="11.5 0.5 11.5 5.50014165 16.5 5.5"></polyline>
</g>
</g>
</g>
</svg></code></pre>
<p>SVG icon generated by Sketch (which is pretty clean anyway,) 903 characters</p>
<pre><code><svg width="25px" height="28px" viewBox="0 0 25 28" xmlns="http://www.w3.org/2000/svg">
<defs></defs>
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g class="table" transform="translate(0.00, -93.00)" stroke="#787878">
<g class="note" transform="translate(4.00, 99.00)">
<polygon class="paper" stroke-linecap="round" stroke-linejoin="round" points="0.5 0.5 11.56 0.5 16.5 5.49 16.5 20.5 0.5 20.5"></polygon>
<polyline class="corner" points="11.5 0.5 11.5 5.50 16.5 5.5"></polyline>
</g>
</g>
</g>
</svg></code></pre>
<p>SVG after my script, 634 characters</p>
<figure>
<pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;svg width="25px" height="28px" viewBox="0 0 25 28" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"&gt;
&lt;!-- Generator: Sketch 41.1 (35376) - http://www.bohemiancoding.com/sketch --&gt;
&lt;title&gt;resources-small&lt;/title&gt;
&lt;desc&gt;Created with Sketch.&lt;/desc&gt;
&lt;defs&gt;&lt;/defs&gt;
&lt;g id="Icons-and-Clouds" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"&gt;
&lt;g id="table" transform="translate(0.000000, -93.000000)" stroke="#787878"&gt;
&lt;g id="note" transform="translate(4.000000, 99.000000)"&gt;
&lt;polygon id="paper" stroke-linecap="round" stroke-linejoin="round" points="0.5 0.5 11.5622559 0.5 16.5 5.49975586 16.5 20.5 0.5 20.5"&gt;&lt;/polygon&gt;
&lt;polyline id="corner" points="11.5 0.5 11.5 5.50014165 16.5 5.5"&gt;&lt;/polyline&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;/svg&gt;</code></pre>
<figcaption>
<p>SVG icon generated by Sketch (which is pretty clean anyway,) 903 characters</p>
</figcaption>
</figure>
<figure>
<pre><code>&lt;svg width="25px" height="28px" viewBox="0 0 25 28" xmlns="http://www.w3.org/2000/svg"&gt;
&lt;defs&gt;&lt;/defs&gt;
&lt;g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"&gt;
&lt;g class="table" transform="translate(0.00, -93.00)" stroke="#787878"&gt;
&lt;g class="note" transform="translate(4.00, 99.00)"&gt;
&lt;polygon class="paper" stroke-linecap="round" stroke-linejoin="round" points="0.5 0.5 11.56 0.5 16.5 5.49 16.5 20.5 0.5 20.5"&gt;&lt;/polygon&gt;
&lt;polyline class="corner" points="11.5 0.5 11.5 5.50 16.5 5.5"&gt;&lt;/polyline&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;/svg&gt;</code></pre>
<figcaption>
<p>SVG after my script, 634 characters</p>
</figcaption>
</figure>
<h2>Cross-platform reliability</h2>
<p>If you compare the old layout to the new layout, the most noticeable change is how the content better fills the available space than before. It’s particularly noticeable inside the app. Before, the layout looked like a website inside an app. Now, it looks like the content is a more unified part of the whole.</p>
<p>In development terms, this refactor has a big performance advantage. The compiled CSS on the app has gone from 19kb to 16kb. The compiled CSS on the site has gone from 34kb to 25kb. Comparing Better to a site laden with JavaScript trackers, performance was never an issue to begin with. Where we really win is in maintainability, now the CSS is much simpler and easier to read.</p>
<figure>
<img src="images/old-news.jpg" alt="Screenshot of the old News layout on the iPad Air 2" width="768" height="576" style="margin-left:auto;margin-right:auto;height:auto;border:1px #ccc solid;">
<figcaption>
<p>Before the overhaul&mdash;on iPad Air 2</p>
</figcaption>
</figure>
<figure>
<img src="images/new-news.jpg" alt="Screenshot of the new News layout on the iPad Air 2" width="768" height="576" style="margin-left:auto;margin-right:auto;height:auto;border:1px #ccc solid;">
<figcaption>
<p>After the overhaul&mdash;on iPad Air 2</p>
</figcaption>
</figure>
<p>This refactor was bigger than planned, but we still have plenty more changes on the roadmap. One of our core principles at Ind.ie is to iterate, rather than work on big upfront design. With this approach we hope to keep making everything we do, incrementally better<abbr title="asterisk">*</abbr>.</p>
<p>In development terms, this refactor has a big performance advantage. The compiled CSS on the app has gone from 19kb to 16kb. The compiled CSS on the site has gone from 34kb to 25kb. Comparing Better to a site laden with JavaScript trackers, performance was never an issue to begin with. Where we really win is in maintainability, now the CSS is much simpler and easier to read.</p>
<p><em><abbr title="asterisk">*</abbr>pun always intended.</em></p>
<p>This refactor was bigger than planned, but we still have plenty more changes on the roadmap. One of our core principles at Ind.ie is to iterate, rather than work on big upfront design. With this approach we hope to keep making everything we do incrementally better.</p>
</div>
<div id="discourse-comments"></div>
</div>
<!-- Ind.ie footer -->
<aside class='fund-us'>
<h2>We need your support</h2>
<p><a href='/about'>We won’t take venture capital</a>. We need your individual support to help us <a href='https://ind.ie/fund'>until we reach sustainability</a>.</p>
<a class='button' href='https://ind.ie/fund'>Fund us</a>
</aside>
<footer class='site-footer'>
<div class='footer-wrap'>
<aside class='ethical-design-badge'>
......
......@@ -154,6 +154,11 @@ pre {
margin-top: 2em;
}
code {
font-size: 18px;
font-size: 1.125rem;
}
pre code.hljs {
margin: -1em;
padding-left: 1em;
......
This diff is collapsed.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment