The collected witterings of Rich Archer https://richarcher.co.uk/feed.xml British web developer; South Africa inhabiter; Web-standards gospeller en-gb Tue, 20 Sep 2016 07:45:42 GMT Why you need a CSS component library https://richarcher.co.uk/articles/2016-09-02/why-you-need-a-css-component-library/ Thu, 08 Sep 2016 12:52:00 GMT rich@richarcher.co.uk (Rich Archer) https://richarcher.co.uk/articles/2016-09-02/why-you-need-a-css-component-library/index.html <p>I’ve <a href="/articles/2013-03-14/cape-town-front-end-developer-meetup/">gone off on one before</a> about the why’s and wherefore’s of being more intelligent about your CSS architectural choices, so I’ll save the long chat, and just assume you’re onboard with the whole idea of styling mostly with classes, tiers of styling specificity, and focussing on reuse.</p> <p>When I’ve spoken to non-CSS developers, the big concern around updating or removing features from a stylesheet is the worry that other pages that make use of the same styles are adversely affected. This concern then leads to either the developer in question considering CSS to be a “Dark Art” - something that it really doesn’t need to be.</p> <h2>Cascading Stylesheets Gonna Cascade</h2> <p>A lot had already been said about using certain patterns of <a href="https://smacss.com/">naming</a> <a href="https://en.bem.info/toolbox/sdk/bem-naming/">conventions</a>, <a href="https://speakerdeck.com/dafed/managing-css-projects-with-itcss">layering of styles</a>, and <a href="https://philipwalton.com/articles/decoupling-html-css-and-javascript/">separations of concerns</a> to reduce styling side effects and bugs. <em>In theory</em>, being sensible about your approach to naming and using classes prevents <em>most</em> styling clashes. That still doesn’t ease the nervous CSS newbie dipping their toe into a well established CSS codebase - and I can see their point.</p> <p>Sadly, in order to be the kind of super-efficient CSS developer we all strive to be, we need to have a complete understanding of the site we are working on. Every browser foible, every odd little <code>@media</code> breakpoint, JS fallback and page state takes time to understand, and just isn’t practical for every single case. This is especially true in an agency environment, where team members can change, or several months can pass between development sprints.</p> <p>Back-enders have it <em>easy</em>.<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup> They get a huge range of testing suites to pick from that will test all their code at a unit and integration level. Once they leave a project, they can offload all their silo’d knowledge into their specs, confident that the tests will serve to remind them if and when they return to the codebase.</p> <p>Not so the keen Stylesheet Adventurer. No matter how closely to the BEM convention they stick, the moment they add an extended class style onto an existing module, a <a href="http://explosm.net/comics/3207/">seed of Doubt</a> will being to germinate in the back on their mind. <em>Are you certain that’s not going to cause issues anywhere else?</em></p> <div class="i-fullwidth"><img src="library.jpg" alt="The Long Room at Trinity College Library" width="900" height="300"></div> <h2>TDD-CSS</h2> <p>Having back-end-like tests for CSS would provide a level of confidence for developers with their own styles. Having confidence in your code means that you aren’t afraid to rip out redundant sections or extend upon existing work from other team members.</p> <p>There have been a some attempts before to solve the ‘how-to-write-tests-for-CSS’ problem, to <a href="https://www.smashingmagazine.com/2015/04/visual-test-driven-development-responsive-interface-design/">varying degrees of success</a>. I can’t help but feel, however, that when the success of your code is almost entirely visual, a visual solution is the most effective option.</p> <p>What would be handy is a facility where a developer could get an at-a-glance overview of all styles, without needing to navigate to every obscure corner of app, or being forced to intentionally misuse a feature in order to see an error message.</p> <p>In the last few years, <strong>living CSS styleguides</strong> have become very popular as a choice of development tool. A separate suite of webpages, sharing the same assets as the main site, but comprised of static HTML patterns to document use cases of CSS. The shining examples of this are <a href="http://getbootstrap.com/css/">Bootstrap’s documentation pages</a>, Github’s <a href="http://primercss.io/">Primer</a>, <a href="http://patterns.alistapart.com/">A List Apart</a>… and, well, all of <a href="http://styleguides.io/">styleguides.io</a></p> <p>The great thing about living styleguides is that they are the tip of a massive and well-established pattern library iceberg. Let’s ignore for now the established guides we have all seen that for logo usage, voice and tone, or coding conventions. Although all are VERY necessary, they constitute only a section of what is possible. Instead, we’ll stick with HTML and CSS components.<sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup></p> <p>CSS Styleguides can be interfaces into your world of CSS patterns. The breadth of that interface is up to you. You may choose to simply display the types of headings, copy and colour swatches available. Or you could go deep and display every single component of your site, such as headers, cards and lists. Maybe take <a href="http://patternlab.io/">Brad Frost’s approach</a> and consider an atomic design methodology; deconstruct your classes from atoms through molecules and up to complex organisms. It is entirely up to you what and how you display your components, as long as you are communicating to your team how a CSS module works, it shouldn’t matter.</p> <p><strong>Component libraries</strong> are an extension upon that idea. Instead of providing a general sense of the look and feel of an app, we go full resolution. Every class, module and component is included. This is not for the designers and brand managers. This is the reference book for the folk at the coal face. If it’s in production code, it should be here too.</p> <p>It’s not simple work by any means, and like traditional spec writing, it can be seen as a bit of a slog sometimes, but once you have all these components, all on one page… Wow, things start to become very interesting.</p> <h2>Component library all the things</h2> <ul> <li> <p><strong>Happy path scenario</strong>: Make a global font size change in your CSS. Instead of checking on each and every page, you simply visit your component library page and scroll through to see if there are any adverse affects. Then you pick up your phone and try it on that as well. All good? Great, carry on with your day.</p> </li> <li> <p>Need to re-theme? Need to test on an ancient browser? Need to test the registration process, but don’t want to spam the servers with fake accounts? Create static components of each state and preserve them in your library for easy checking in the future.</p> </li> <li> <p>Create static versions of multi-step logins, or invalid form fields without having to manually go through the process yourself, every single time.</p> </li> <li> <p>Add in some automated testing, for example with <a href="https://github.com/BBC-News/wraith">Wraith</a>, that compares a screenshot of your current styleguide against, say that of an earlier deployment and reports back with any differences between the two.</p> </li> </ul> <p>A component library, populated well, can be your documentation of why a pattern was chosen, a sandbox for new features, a debugger and a testing tool.</p> <p>We’ve been using component libraries for a couple of years now, and the results are obvious. No more ‘is that class still needed’ questions, no more creating elaborate data structures to see if an extra long peice of content breaks the layout. Glorious.</p> <p>My ‘oooh yeeaaah’ moment was when I realised that I could now easily refactor a global component to take advantage of a new CSS feature without needing to create a new component class and replace HTML. I didn’t need to manually check all instances of it in production to see if it worked. I could probably count the number of times I’ve been able to refactor CSS this easily on one hand.</p> <p>Having the ability to change your entire site’s look and feel, or conversely, changing the entire way your pages are constructed <em>without</em> changing the look and feel at all, and without having to manually check and re-check all the pages across your site? That’s pretty powerful.</p> <p>I think that we should be trying to give <em>everyone</em> in a development team ownership of CSS development. Style guides are a step towards that; with a built-in birds-eye-view of all your CSS code, it’s possible to see all the ramifications of updating styles. If we can reduce the fears of introducing regression bugs or developing new features that collide with existing elements, then we can focus on the actual details of CSS, rather than the implementation. You know; the <em>fun stuff</em>!</p> <hr class="footnotes-sep"> <section class="footnotes"> <ol class="footnotes-list"> <li id="fn1" class="footnote-item"><p>Oh god, that’s going to be engraved on my tombstone after an angry mob of Rails developers lynch me. If I’m <code>found_dead(Time.now, 1.month.from_now)</code> please narrow the list of suspects down to known Rubymine users. <a href="#fnref1" class="footnote-backref">↩︎</a></p> </li> <li id="fn2" class="footnote-item"><p>In the Global Library that is all possible types of styleguide, let us venture into the… <em>HTML Pattern section</em>? The <em>CSS Components aisle</em>? Metaphors are hard, man. <a href="#fnref2" class="footnote-backref">↩︎</a></p> </li> </ol> </section> Taking back control of SASS colour variables https://richarcher.co.uk/articles/2016-07-01/taking-back-control-of-sass-colour-variables/ Fri, 01 Jul 2016 08:18:00 GMT rich@richarcher.co.uk (Rich Archer) https://richarcher.co.uk/articles/2016-07-01/taking-back-control-of-sass-colour-variables/index.html <p>The following is a honest-to-god chunk of SASS/SCSS code we used in a large-ish project not too long ago. I don’t expect you to actually read it - just let your eyes skim over the horror for a moment.</p> <pre class="hljs"><code><span class="hljs-variable">$black</span>: rgb(<span class="hljs-number">0</span>,<span class="hljs-number">0</span>,<span class="hljs-number">0</span>); <span class="hljs-variable">$basecolor</span>: <span class="hljs-number">#333</span>; <span class="hljs-variable">$grey</span>: lighten(rgb(<span class="hljs-number">0</span>,<span class="hljs-number">0</span>,<span class="hljs-number">0</span>), <span class="hljs-number">46.5%</span>); <span class="hljs-comment">// #777</span> <span class="hljs-variable">$lightgrey</span>: lighten(rgb(<span class="hljs-number">0</span>,<span class="hljs-number">0</span>,<span class="hljs-number">0</span>), <span class="hljs-number">58.6%</span>); <span class="hljs-comment">// #959595</span> <span class="hljs-variable">$lighterlightgrey</span>: <span class="hljs-number">#a9a9a9</span>; <span class="hljs-variable">$lightergrey</span>: lighten(rgb(<span class="hljs-number">0</span>,<span class="hljs-number">0</span>,<span class="hljs-number">0</span>), <span class="hljs-number">79%</span>); <span class="hljs-comment">// #c9c9c9</span> <span class="hljs-variable">$lighterergrey</span>: lighten(rgb(<span class="hljs-number">0</span>,<span class="hljs-number">0</span>,<span class="hljs-number">0</span>), <span class="hljs-number">90%</span>); <span class="hljs-comment">// #e6e6e6</span> <span class="hljs-variable">$lightestgrey</span>: <span class="hljs-number">#f2f2f2</span>; <span class="hljs-variable">$white</span>: rgb(<span class="hljs-number">255</span>,<span class="hljs-number">255</span>,<span class="hljs-number">255</span>); <span class="hljs-variable">$lightblue</span>: <span class="hljs-number">#00a5d8</span>;<span class="hljs-comment">//hyperlink blue</span> <span class="hljs-variable">$storyblue</span>: <span class="hljs-variable">$lightblue</span>; <span class="hljs-variable">$blue</span>: <span class="hljs-number">#0085ca</span>; <span class="hljs-comment">//brand colour</span> <span class="hljs-variable">$electric-booga-blue</span>: <span class="hljs-number">#07d7d5</span>; <span class="hljs-variable">$selected-darkblue</span>: <span class="hljs-number">#35596d</span>; <span class="hljs-variable">$last-minute-orange</span>: <span class="hljs-number">#ff8441</span>; <span class="hljs-variable">$discounted-red</span>: <span class="hljs-number">#ee3124</span>; <span class="hljs-variable">$so-many-deals-red</span>: <span class="hljs-number">#c91e1f</span>; <span class="hljs-variable">$orange-you-glad</span>: <span class="hljs-number">#FF780A</span>; <span class="hljs-variable">$orange-cta-light</span>: <span class="hljs-number">#fc892b</span>; <span class="hljs-variable">$orange-cta-dark</span>: <span class="hljs-number">#e8640c</span>; <span class="hljs-variable">$main-nav-seperator-color</span>: <span class="hljs-number">#3b3b3b</span>; ...*snip* (continues for another 30 lines) </code></pre> <p>A hodge-podge of both over-vague and too-specific variable names, with a scattering of passive aggression in there for good measure. A few trying-to-be-helpful comments, variables assigning other variables, at least 7 different shades of grey<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup> - in short, a mess.</p> <h2>Long lists suck</h2> <p><strong>Lists</strong> are handy to have, but their effectiveness is inversely proportional to their length. The longer a list becomes, the harder it is for us humans to parse and channel that information into something useful.<sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup></p> <p><strong>SASS variables</strong> are fantastic. Reading a variable like <code>$facebook_brand</code> in code, rather than a meaningless RGB value is brilliant. But that helpfulness doesn’t scale. Not all colours are as memorable or have such a useful single-purpose name.<sup class="footnote-ref"><a href="#fn3" id="fnref3">[3]</a></sup></p> <p>Therefore, it’s easy to see why a combination of 2 useful-but-not-<em>super</em>-useful technologies can become problematic after a while.</p> <p>In practice, long lists of SASS variables are painful to read, parse, and subsequently, care about. So it’s very easy to end up with one or several of the following:</p> <ol> <li><strong>Terrible variable naming</strong> : The developer needs a specific colour, searches through the list and can’t find a colour close enough, so hastily adds another colour variable, with a suitably specific name: <code>$reallyLightGreyThisTimeIMeanIt</code>.</li> <li><strong>Duplicating colours</strong> : The developer doesn’t find the colour needed, even though it does exist, so adds it in a duplicate (<a href="http://www.slideshare.net/stubbornella/our-best-practices-are-killing-us/4-FACEBOOK_BLUE_261Wednesday_March_30">or painfully similar</a>) colour definition with another hastily thrown together variable name.</li> <li><strong>Overriding variables</strong> : The developer adds <code>$calltoaction</code> not noticing that variable already exists, overriding the original colour with the new and introducing regression errors.</li> <li><strong>Rage quitting the whole variable nonsense</strong> : The developer hard codes the colour into the CSS rather than using colour variables, because I’m not going to spend five minutes crawling through the variables trying to find the right one.</li> </ol> <p>I wouldn’t blame anyone for doing any of those - it’s not their fault that this unsorted mess of variables is hard to use.</p> <p>Like a lot of the very useful features in SASS, they are the tools that, when used improperly, allow users to make their own horrible flavours of code spaghetti.</p> <p>For example, SCSS <a href="http://sass-lang.com/guide#topic-3">selector nesting</a> of style definitions are an <em>incredibly</em> powerful function, but nest too deeply and you end up entering a CSS specificity battle with your past self. To the point where sensible SASS guidelines now recommend <a href="https://www.sitepoint.com/beware-selector-nesting-sass/">avoiding nesting unless absolutely necessary</a>.</p> <p>It’s the same with colour variables. A simple concept that is far too prone to causing more hassle than the problem it was initially meant to solve.</p> <blockquote> <p><q>[They] were so preoccupied with whether or not they <em>could</em> that they didn’t stop to think if they <em>should</em>.</q> <cite><a href="http://jurassicpark.wikia.com/wiki/Ian_Malcolm">Dr Ian Malcolm</a></cite></p> </blockquote> <h2>Mo’ variables, mo’ problems</h2> <p>I’m a simple man. All I ask is for an approach that allows me to:</p> <ol> <li><strong>Globally assign colours to variables</strong> The main reason for using SASS variables in the first place. Assigning names to variables and using them throughout the codebase means that it’s easier to keep track of the colours in use should we need to globally change them.</li> <li><strong>Use a memorable naming convention</strong> I know from experience that playing the game ‘<em>How do I spell that variable?</em>’ is a long and torturous process. Having to stop working in one document to look up a variable declaration in another, only to realise you’d used a been misspelling the variable is a morale-sapping experience. Tiny little delays like that can really interrupt a development flow.</li> <li><strong>Enforce a naming convention</strong> You may have come up with a super-simple approach to naming your variables - but no-one <em>has</em> to follow it. Are you going to fastidiously read every pull request, and leave helpful comments about how it should be named? Ain’t nobody got time for that.</li> <li><strong>Increase the readability</strong> Someone very wise once wrote that ‘<a href="#long-lists-suck">long lists suck</a>’. You can sort the lists somehow, or add in line-breaks - maybe a comment or two, but again, it’s not enforceable, it is painful to maintain, and it’s even worse to read.</li> <li><strong>Gracefully handle errors</strong> SASS’s default behaviour of aborting compilation when an unknown variable is used is not very helpful, especially when refactoring SCSS code. Isn’t there some way we could have a graceful fallback of some sort should a colour not exist?</li> </ol> <p>Fortunately, with SASS’s lovely <a href="http://sass-lang.com/documentation/file.SASS_REFERENCE.html#maps">map data types</a> and a few SASS functions, it is possible to regain some control of unwieldy lists. Let’s run through it.</p> <p>Firstly, we created a nested SASS map object, into which we can add all the colour variables:</p> <pre class="hljs"><code><span class="hljs-variable">$swatches</span>: ( grey: ( light: lighten(rgb(<span class="hljs-number">0</span>,<span class="hljs-number">0</span>,<span class="hljs-number">0</span>), <span class="hljs-number">79%</span>), base: <span class="hljs-number">#a9a9a9</span>, ), blue: ( light: <span class="hljs-number">#00a5d8</span>, base: <span class="hljs-number">#0085ca</span>, dark: <span class="hljs-number">#07d7d5</span> ), orange: ( base: <span class="hljs-number">#FF780A</span>, dark: <span class="hljs-number">#e8640c</span>, ) ... ); </code></pre> <p>We’ve grouped the colours firstly by broad colour definition, and finally defined each colour either <code>base</code>, <code>dark</code> or <code>light</code>. Already we’re tackling the readability issue - grouping by broader chunks of code makes lists far easier for humans to scan through.</p> <p>Once a variable is in a map like this, the only real way to get them out is via a custom SASS function and a couple of <a href="http://sass-lang.com/documentation/Sass/Script/Functions.html#map-functions">tasty SASS helpers</a>. The function will require 2 parameters; a colour name and a ‘tone’:</p> <pre class="hljs"><code> @function swatch(<span class="hljs-variable">$swatch</span>, <span class="hljs-variable">$tone</span>) { @<span class="hljs-keyword">if</span> map-has-key(<span class="hljs-variable">$swatches</span>, <span class="hljs-variable">$swatch</span>) { @<span class="hljs-keyword">if</span> map-has-key(map-get(<span class="hljs-variable">$swatches</span>, <span class="hljs-variable">$swatch</span>), <span class="hljs-variable">$tone</span>) { @return map-get(map-get(<span class="hljs-variable">$swatches</span>, <span class="hljs-variable">$swatch</span>), <span class="hljs-variable">$tone</span>); } } } </code></pre> <p>So now we have a basic implementation: <code>swatch(blue, base)</code> will return <code>#0085ca</code>. Nice!</p> <p>Because we now have programmatic access to our colours, we can build on this wrapper function to start addressing some of the earlier issues.</p> <p>Let’s make a few assumptions about our variable map. For example, let’s assume that there must always be a <code>base</code> variable for each colour. Working with that, we can then start incorporating some graceful fallbacks for undefined tones, as well as add in some other nice-to-haves.</p> <pre class="hljs"><code>@function swatch(<span class="hljs-variable">$swatch</span>, <span class="hljs-variable">$tone</span>: <span class="hljs-string">'base'</span>) { <span class="hljs-variable">$swatch-error</span>: <span class="hljs-number">#f00</span>; @<span class="hljs-keyword">if</span> map-has-key(<span class="hljs-variable">$swatches</span>, <span class="hljs-variable">$swatch</span>) { @<span class="hljs-keyword">if</span> map-has-key(map-get(<span class="hljs-variable">$swatches</span>, <span class="hljs-variable">$swatch</span>), <span class="hljs-variable">$tone</span>) { @return map-get(map-get(<span class="hljs-variable">$swatches</span>, <span class="hljs-variable">$swatch</span>), <span class="hljs-variable">$tone</span>); } @<span class="hljs-keyword">warn</span> <span class="hljs-string">"Invalid tone: `#{$swatch}` - `#{$tone}`."</span>; @return swatch(<span class="hljs-variable">$swatch</span>); } @<span class="hljs-keyword">warn</span> <span class="hljs-string">"Invalid swatch: `#{$swatch}`."</span>; @return <span class="hljs-variable">$swatch-error</span>; } </code></pre> <p>So given our previous <code>$swatches</code> map - the following should be the case:</p> <p><code>swatch(blue)</code> will return <code>#0085ca</code>, <code>swatch(blue, light)</code> will give us <code>#00a5d8</code>, <code>swatch(blue, herpderp)</code> will fall back to the base colour of <code>#0085ca</code> again.</p> <p>Using <code>swatch(madeup, light)</code> will return <code>#f00</code> as that map doesn’t exist at all.</p> <p>Lastly, error logging is added via the <code>@warn</code> method for further bug tracking.</p> <p>We’re done! By leveraging the built-in functions of SASS, we’ve constructed a far more useful map of colours that can be easily parsed by both computer and coder. We have graceful fallbacks and a sensible naming convention that is simple to understand and extend upon.</p> <h2>Closing thoughts</h2> <ul> <li> <p>If you take nothing else away from this article, I heartily recommend you make use of a CSS or <a href="https://github.com/brigade/scss-lint">SCSS linter</a>. Yes, it will annoy your team members, yes your CI build steps will fail at first for totally infuriating reasons - but you get to enforce some super-useful steps, such as colour literals only being used in variable definitions. No more hard-coding colours into the CSS rules.</p> </li> <li> <p>The swatch names I’ve chosen here are for demonstration purposes only. Being the old CSS warhorse that I am, I’m still not keen on naming a class (or variable in this case) ‘blue’, just in case the site is somehow redesigned <em>with just the CSS being edited</em> and ‘blue’ is defining a bright yellow colour. That’s my personal preference. I’ve always liked to use names that seem indicative of a colour but ultimately doesn’t mean anything… basically, <a href="https://www.dulux.ca/pro/colour/browse-our-colours">Dulux paint names</a>… so ‘majestic’ for purple, or ‘jaffa’ for orange.</p> </li> <li> <p>Also, remember that the names you use are purely subjective and that these names <strong>only</strong> need to have semantic meaning for your team of developers. If ‘badger’ speaks to your team as ‘green’, and ‘happiness’ is ‘orange’, then all power to you. Remember, rather than having a list of 40-odd variables, the use of maps mean that we’re only going to need to remember 6 or so, and after that, it’s combinations of tone keywords. In this case, <strong>‘Memorable’ &gt; ‘technically correct’</strong>.</p> </li> <li> <p>Most of the time you’re probably going to need more than 3 tones for each colour group, so the illustrated <code>light</code>/<code>base</code>/<code>dark</code> combo is not going to do the job. So far, I’ve found relative success starting with that, and then padding out the extremities and midpoints with <code>x-light</code>/<code>mid-light</code>, and so on. The only thing to remember is that the use of these tone-names needs to be consistent across your colour maps.</p> </li> <li> <p><strong>The perfect use case</strong>: Think of your co-developers trying <code>swatch(ocelot)</code>, and needing it to be a little lighter, so trying out <code>swatch(ocelot, light)</code> and getting the exact colour needed, all without the SASS compilation freaking out, or needing to check a list in a separate file, allowing them to get on with their work seamlessly. Lovely.</p> </li> <li> <p>Only occasionally have I found that I’ve ended up with more than 8 colours in a single map, at which point, I’d suggest taking the opportunity to refactor your code and break those colours out into 2 or more separate objects.</p> </li> </ul> <hr class="footnotes-sep"> <section class="footnotes"> <ol class="footnotes-list"> <li id="fn1" class="footnote-item"><p>In which Christian Grey reveals a <strong>shameless</strong> amount of ankle. <a href="#fnref1" class="footnote-backref">↩︎</a></p> </li> <li id="fn2" class="footnote-item"><p>Remember this next time you’re wandering around a supermarket with a list in hand, and have to make the long trek back to the bread aisle because you didn’t notice ‘bagels’ further down. <a href="#fnref2" class="footnote-backref">↩︎</a></p> </li> <li id="fn3" class="footnote-item"><p>I’m looking at you, <code>$main-nav-seperator-color</code> - I mean, you’re not even spelled correctly! <a href="#fnref3" class="footnote-backref">↩︎</a></p> </li> </ol> </section> (Over)thinking about custom elements https://richarcher.co.uk/articles/2014-10-12/overthinking-about-web-components/ Sun, 12 Oct 2014 08:01:00 GMT rich@richarcher.co.uk (Rich Archer) https://richarcher.co.uk/articles/2014-10-12/overthinking-about-web-components/index.html <p>With the promise of encapsulated new behaviours and styling, the ability to create new HTML elements, and to have all that power easily share-able within the community - Web Components hold enough promise to be the <a href="http://www.theonion.com/video/sony-releases-new-stupid-piece-of-shit-that-doesnt,14309/">Next Big Thing</a>.</p> <p>If you haven’t yet got the full skinny on Web Components and their potential, I can’t recommend reading Peter Gasston’s excellent <a href="http://coding.smashingmagazine.com/2014/03/04/introduction-to-custom-elements/">introduction to Custom Elements</a> enough. In fact, even if you consider yourself fairly up-to-date and you <em>haven’t</em> read it, go do yourself a favour. I’ll wait. Go on.</p> <p>It’s <em>cool</em>, right? We have in our hands the power to add new features to browsers as technologies and requirements of the web change. We essentially short-cut the previous routes of going through the labyrinthine halls of the W3C spec writers, and can quickly prototype an <a href="http://beinglimited.com/misconception-about-mvp/">MVP</a>, deploy, learn, and iterate.</p> <p>The theory is that once developed, you can decide to publish you shiny new component <a href="http://customelements.io/">somewhere</a> so other folk can use it. In theory, the best will rise to the top of the heap, gain the most visibility, be adopted by everyone, make the web a better place and <a href="https://www.youtube.com/watch?v=rGnH6JPsv7E">everything is awesome</a><sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup>.</p> <p>Full disclosure: I had my concerns about web components when I first heard of them. The examples I read about and had explained to me by enthusiastic early adopters were setting off my Progressive Enhancement and Accessibility senses<sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup>.</p> <p>To utterly misquote <a href="http://www.imdb.com/title/tt0057012/">Dr. Strangelove</a>: <q>The technology of web components is easily within the means of any developer; it requires only the will to do so.</q></p> <div class="i-fullwidth"><img src="strangelove.jpg" alt="Dr. Strangelove (1964)" width="700" height="284"></div> <p><em>Anyone</em>. Like, really? Anyone could develop these? Surely that’s a terrible idea!</p> <p>Have a look at how many jQuery plugins are there that provide some level of JS functionality without a <a href="/articles/2014-03-04/do-we-need-progressive-enhancement-in-our-web-apps/">PE-style</a> fallback. How many plugins, developed with the best of intentions, break on newer browsers, are ill supported, left to go stale when the author moves on to pastures new?</p> <p>It seemed to me that aspects of accessibility and maintainability are important to spec writers but not to enough developers of plugins and polyfills, and so it would continue with Web Components. With the web components atomic bomb, I reasoned, we were going to break the Web.</p> <p>“People are stupid,” I said, “we’ll end up with a hundred different variations of link elements, one for each social platform, none of which are as good as the original accessible HTML element.”</p> <div class="i-fullwidth"><img src="war-room.jpg" alt="Dr. Strangelove (1964)" width="700" height="294"></div> <p><a href="http://a11yproject.com/about.html">Accessibility is hard</a>. As much as people reassured each other that fallbacks to standard elements and <a href="http://html5doctor.com/using-aria-in-html/">ARIA roles</a> will be the way forward with regard to making web components future friendly, I remained skeptical, and that we would end up developing the components we deserve, not the components we need.</p> <p>But again, I need to remember that the web is an ever-evolving continuum. As much as I want backwards compatibility for as long as possible, I also want the web to be forging onwards in bold new directions. And that is cool and amazing, but also scary and terrifying. I look forward to the introduction of the <code>&lt;hologram&gt;</code> element, but the backward-compatibility concerns are potentially <em>staggering</em>.</p> <p>If I want that, then I should trust other people do as well, and with these tools we have the ability to get <a href="http://webcomponents.org/">coding</a> now. As <a href="http://www.brucelawson.co.uk/2014/notes-on-accessibility-of-web-components/">Bruce Lawson</a> put it: <q>My message to accessibility advocates is ‘passion – great. But with pull requests, please.’</q></p> <p>We have a unique opportunity to shape the future of the web at a grass-roots level <em>right now</em>. I’m off to start developing.</p> <h2>Required reading from far smarter folk</h2> <ul> <li><a href="http://customelements.io/">Customelements.io</a></li> <li><a href="http://webcomponents.org/">Webcomponents.org</a></li> <li><a href="http://www.brucelawson.co.uk/2014/notes-on-accessibility-of-web-components/">Bruce Lawson - Notes on accessibility of web components</a></li> <li><a href="https://adactio.com/journal/7431">Jeremy Keith - Web components</a></li> </ul> <hr class="footnotes-sep"> <section class="footnotes"> <ol class="footnotes-list"> <li id="fn1" class="footnote-item"><p>Sidenote: Is there a such a thing as an anti-sarcasm element? <code>&lt;earnest&gt;</code>, maybe? Because reading that last line back sounds VERY sarcastic. It’s not. I think this stuff is brilliant. No really. No <em>really</em>. <a href="#fnref1" class="footnote-backref">↩︎</a></p> </li> <li id="fn2" class="footnote-item"><p>Kind of like <a href="http://tvtropes.org/pmwiki/pmwiki.php/Main/SpiderSense">Spider Senses</a> but with better screen reader support <a href="#fnref2" class="footnote-backref">↩︎</a></p> </li> </ol> </section> Do we still need Progressive Enhancement in web apps? https://richarcher.co.uk/articles/2014-03-04/do-we-need-progressive-enhancement-in-our-web-apps/ Tue, 04 Mar 2014 07:02:00 GMT rich@richarcher.co.uk (Rich Archer) https://richarcher.co.uk/articles/2014-03-04/do-we-need-progressive-enhancement-in-our-web-apps/index.html <p>There has been a heck of a lot said about <abbr title="Progressive Enhancement">PE</abbr> in the last month or so, most notably from my favourite super-smart thought leaders, <a href="http://adactio.com/journal/6692/">Jeremy Keith</a> and <a href="http://unstoppablerobotninja.com/entry/platformed/">Ethan Marcotte</a> about the need to remember the lessons of the past, and keep progressive enhancement a key concern in one’s daily development cycles.</p> <p>It’s a good thing to keep front of mind, especially when (to my mind, deliberately inflammatory) articles about <a href="http://tomdale.net/2013/09/progressive-enhancement-is-dead/">PE being dead</a> gain traction and encourage what I would consider a step backwards in that aspect of web development.</p> <p>It’s an important question to ask, however. Why, when we have a proliferation of <a href="http://angularjs.org/">amazing</a> <a href="http://backbonejs.org/">JS</a> <a href="http://www.cappuccino-project.org/">web-app</a> <a href="http://chaplinjs.org/">libraries</a> <a href="http://echo.nextapp.com/site/">that</a> <a href="http://emberjs.com/">allow</a> <a href="http://www.bbc.co.uk/glow/">us</a> <a href="http://www.gwtproject.org/">to</a> <a href="http://javascriptmvc.com/">do</a> <a href="http://knockoutjs.com/">magnificent</a> <a href="http://mootools.net">things</a> <a href="http://jquery.com">in</a> <a href="http://dojotoolkit.org/">the</a> <a href="http://www.sencha.com/products/extjs/">browser</a> should we have to develop the same application twice? We live in a world where screen reader JavaScript penetration is <a href="http://webaim.org/projects/screenreadersurvey5/#javascript">97.6%</a>, and one of the Big Four browsers doesn’t even allow users to easily <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=873709&amp;resub&amp;utm_source=feedly">turn off JavaScript</a>.</p> <blockquote> <p><q>Why should I have to develop (and pay for) an app that renders once in HTML, before being overwritten by the same app written in a different language?</q> <cite>– Recalcitrant Crowd of Developers</cite><a href="id:whytwice"></a></p> </blockquote> <h2>Does it take a lickin’ and keep on tickin’?</h2> <p>Of the 3 main aspects of front-end development, HTML, CSS, and JS, JavaScript is by far the most fragile. HTML (<a href="http://en.wikipedia.org/wiki/HTML5#Error_handling">especially HTML5</a>) handles malformed structure in a reasonably understandable way. CSS silently chooses to <a href="http://www.w3.org/TR/CSS2/conform.html#errors">ignore rules</a> it doesn’t understand. JS needs feature detection. Drop in an unchecked <a href="http://www.iwanttouse.com/#getelementsbyclassname"><code>document.getElementsByClassName</code></a> into anything less than IE9 and, well, the results may yeild unexpected results. Heck, forget to add a semi-colon to the right place, a dependancy fails to download, accidentally redefine a variable; JavaScript packs up and goes home at the first sign of trouble.</p> <p>PE is not just about feature detection. It’s about ensuring that when parts of the site is broken, can other aspects still function. In other words, the parts of a site that do not <a href="http://responsivenews.co.uk/post/18948466399/cutting-the-mustard">cut the mustard</a> in a browser shouldn’t cause the entire site to become unusable.</p> <p><a href="http://christianheilmann.com/2012/02/16/stumbling-on-the-escalator/">Christian Heilmann</a> uses the ‘escalators and elevators’ analogy. When an elevator breaks down, it’s broken and useless. When an escalator breaks down, it becomes a staircase; still useable, just without the extra polish it had before. That’s how we should develop our sites. Embracing the meaning of PE ensures that we can be confident that when (not if) things go “kaka” it should function to some extent.</p> <h3>“Not supported” !== “Ignored”</h3> <p>One of the big points I took away from Jeremy’s post was that “The web is not a platform. It’s a continuum”. From Ethan’s it was that in this business “we play the long game”. Browsers do not pop out of existence the moment we stop supporting them. They’re still out there, used by certain demographics for various reasons, and they still require access to your content.</p> <p>Development time <em>costs</em>. If it didn’t we’d probably end up “supporting” all browsers <em>ad-infinitum</em>. At some point, however, the project purse-holder will decide that it’s not worth the time and effort required to support a particular browser, and you’ll not spend as much time ensuring the <a href="http://www.paulirish.com/2011/tiered-adaptive-front-end-experiences/">HD experience</a> for that section of the audience. They may get the lesser, degraded version without fancy bookmarkable URLs, indeed, they might not even get anything beyond a linear layout and a nod towards typography if that’s what the product owner deems acceptable. What matters is that they can always reach your content.</p> <p>What “support” means to you and your team can be a many varied thing - but as long as you’ve coded your site using proper web-standards, the risk of your site not working <em>at all</em> is minified.</p> <p>I like to ensure that the site I work on can be accessed via the lowest featured browser I can find, arguably <a href="http://lynx.browser.org/">Lynx</a> - a command line based browser that only understands HTML. <a href="http://blog.paciellogroup.com/2014/02/doesnt-work-lynx/">It’s not perfect</a>, but it’s a good indicator of what is available on your site to the lowest common denominator.</p> <p>PE provides you with the confidence that the content is at the very least available to every single one of your users, even if the CSS isn’t rendering or JS playing nicely.</p> <h3>SEO</h3> <p>This is the one that usually has the biggest impact in a discusson regarding PE, because it is the one that has the potential to hit the wallet hardest. If you want search engine traffic coming to your site, you need your site to be <a href="https://support.google.com/customsearch/answer/72366?hl=en">readable to search engines</a>.</p> <p>Much discussion is made in the JS web-app world about how to achieve this. Talk of developing a server side generated equivalent that is <a href="http://www.yearofmoo.com/2012/11/angularjs-and-seo.html">hidden behind a hashbang</a>, or that <a href="https://prerender.io/how-it-works">renders HTML in PhantomJS</a>, using <a href="http://www.angularjsseo.com/">3rd party services</a> that will make your content avilable to (some) search engines via a proprietary specification.</p> <p>Whichever way, the user is still required to develop 2 versions of the site, one client and one server, which no-one really likes, and is a practice that does <a href="#whytwice">raise familiar sounding questions</a>.</p> <p>For my money, if the HTML first layered on JS and CSS approach is not for you, and you absolutely, positively have to have the latest and greatest web-app running on your site - the hard work achieved by the likes of <a href="http://nerds.airbnb.com/isomorphic-JavaScript-future-web-apps/">AirBnB</a>, <a href="https://www.meteor.com/">Meteor</a> and <a href="http://artsy.github.io/blog/2013/11/30/rendering-on-the-server-and-client-in-node-dot-js/">Artsy</a> looks the best bet - a single codebase useable on both the server and front end.</p> <p>Perhaps this is the Holy Grail we’ve all been looking for?</p> <h2>Every time you say “it depends”, we all take a drink</h2> <p>Ultimately, Progressive Enhancement is an opt-in thing. If you genuinely don’t think you’ll ever need the benefits of PE, don’t utilise it. If the “content” your site provides is transient and shouldn’t be indexable, it’s goals simply do not have a fallback alternative, or you just don’t care, then maybe you can skim through this article with casual indifference.</p> <p>I feel, however, that the cases when that is justifiable are limited. For the majority of cases, PE is still highly relevant, and necessary.</p> Generating, Adding, and Using Multiple SSH keys https://richarcher.co.uk/articles/2013-06-04/generating-adding-and-using-ssh-keys/ Tue, 04 Jun 2013 17:54:00 GMT rich@richarcher.co.uk (Rich Archer) https://richarcher.co.uk/articles/2013-06-04/generating-adding-and-using-ssh-keys/index.html <p>Having “One Key to Rule Them All” can be a little concerning when it comes to SSH keys. Single points of failure are not amazing. Let’s spread the risk a little.</p> <p>If you find that you need to work with multiple servers (quite likely), multiple Heroku accounts (very likely) or the myriad other services that require a SSH key to get started - Github, BitBucket et al (very, very likely). No-one enjoys having a single point of failure, and going on past experience, it is incredibly annoying having all your services suddenly fail on you if your private key corrupts, mysteriously vanishes or is somehow compromised.</p> <h2>Creating SSH keys</h2> <p>From your command line, navigate to the directory that stores your SSH keys</p> <pre class="hljs"><code>$ <span class="hljs-built_in">cd</span> ~/.ssh </code></pre> <p>Run the key generation command:</p> <pre class="hljs"><code>$ ssh-keygen </code></pre> <p>This will return the following:</p> <pre class="hljs"><code>Generating public/private rsa key pair. Enter file <span class="hljs-keyword">in</span> <span class="hljs-built_in">which</span> to save the key (/Users/buzz.lightyear/.ssh/id_rsa): </code></pre> <p>Here you would enter the location and name of the key you wish to save - for example <code>foo/new.key.for.github</code>. As the prompt says, leaving this blank generates the standard key <code>id_rsa</code>.</p> <pre class="hljs"><code>Enter passphrase (empty <span class="hljs-keyword">for</span> no passphrase): Enter same passphrase again: </code></pre> <p>Enter your secret passphrase, and you’re done.</p> <pre class="hljs"><code>The key fingerprint is: e8:bf:af:71:b4:b3:32:3a:45:5a:c5:a6:53:d4:74:13 buzz.lightyear@Infinity.local The key<span class="hljs-string">'s randomart image is: +--[ RSA 2048]----+ | +ooE.. | | . + .o | | o + | | +.+ | | S.S. | | . ... | | o.* | | .* + | | o+=. | +-----------------+ </span></code></pre> <p>With regard to passphrases, the temptation might be to leave this blank. Try not to do this; it’s the equivalent of locking your car and then hiding the keys under the back wheels. All it would take is for someone to access your computer and they’ve also access to your remote business.</p> <h1>Adding to the key manager</h1> <p>If you are frequently accessing a server and, frankly, the constant requests for your passphrase are becoming a little draining, then you might consider adding your key to the SSH agent.</p> <p>The SSH agent takes care of the authentication for you so that you don’t have to type in passwords at the terminal. Obviously, the tradeoff for convenience is the drop in security - anyone with access to your personal machine could gain access to your servers that use this particular key - the choice is yours.</p> <p>With the default SSH key (<code>id_rsa</code>) this is as simple as typing in <code>ssh-add</code> into your command line, but you’ve got so many more keys now - so add an extra parameter as follows:</p> <pre class="hljs"><code>$ ssh-add foo/new.key.for.github </code></pre> <p>It should ask for your passphrase if you provided one, and will reward you with your equivalent of this message:</p> <pre class="hljs"><code>Identity added: /Users/buzz.lightyear/.ssh/andys-house (/Users/buzz.lightyear/.ssh/andys-house) </code></pre> <p>SSH-Agent will securely save your passphrase so that you don’t need to type it in each and every time for this session. I find that on closing my terminal, I’m required to repeat this process the next time - which is a good compromise for me.</p> <p>For the fully automated approach, you could tie your ssh-keys into your OSX keychain, the <a href="https://help.github.com/articles/working-with-ssh-key-passphrases">Github.com help docs</a> are pretty useful for getting started.</p> <h1>Further reading:</h1> <ul> <li><a href="https://wiki.archlinux.org/index.php/SSH_Keys">wiki.archlinux.org</a></li> <li><a href="http://www.robotgoblin.co.uk/blog/2012/07/24/managing-multiple-ssh-keys/">Managing multiple SSH keys</a></li> </ul> SSH keys, spying, and such https://richarcher.co.uk/articles/2013-06-02/ssh-keys-spying-and-such/ Sun, 02 Jun 2013 17:03:00 GMT rich@richarcher.co.uk (Rich Archer) https://richarcher.co.uk/articles/2013-06-02/ssh-keys-spying-and-such/index.html <p>Do you push stuff up to GitHub? Heroku? A remote repository of any kind? Chances are that you’ve been asked to “simply upload your SSH keys” to some site or another.</p> <p>If you are anything like me, you’ve nothing but a vague idea what SSH keys are, you’ve simply googled and found a link similar to <a href="https://help.github.com/articles/generating-ssh-keys">the Github help</a> pages, followed the 4 steps and everything seems to work. Huzzah! What exactly did you just do? What does SSH actually mean? It’s time for an elaborate explaination.</p> <h2>Excruciating Cold War analogy of SSH keys</h2> <p>Let’s say that you need to pass a secret package of microfilm securely with another person in return for nuclear plans, but don’t know what he/she looks like and don’t want your package to fall into the wrong hands. How do you know who to trust?</p> <div class="i-fullwidth"><img src="the-spy-who-came-in-from-the-cold.jpg" alt="image" width="700" height="260"></div> <p>You could arrange to meet at a ski resort and pass long, elaborate coded phrases between one another about favourite brands of cigarettes until both of you are convinced of the other’s credentials.</p> <p>At this point you could (most likely) swap microfilm baked into a ceramic cat with the nuclear plans embedded in a Kandinsky painting, and disappear into the night.</p> <p>The problem with this approach is that at some other point in the past - someone will need to have arranged shared passwords. These passwords could be intercepted by unscrupulous types, and before you know it, ‘Comrade Zero’ has gone to your rendezvous point, used <em>your</em> secret phrases and stolen your nuclear plans and given your contact a microfilm full of holiday photos in what will ultimately prove to be another powerful blow against the Capitalist West.</p> <p>Alternatively, both parties could have a padlock and a key. They send their padlock to their opposite number with instructions to bring it to the meeting point, with respective packages locked inside boxes.</p> <p>Once they meet, all it takes is a simple check to see that each padlock can be opened by the other person’s key and you’re home free.</p> <p>If both padlocks cannot be opened, then there is a reasonable chance that one of you is a fraud, the deal is seen as a bust and what follows is almost certainly an exhilarating car chase through Prague.</p> <p>What I’m saying here is that passwords have a single point of failure; giving the opposing party the a padlock that can only be unlocked your private key reassures both sides that the other isn’t a KGB operative, and can be trusted enough to deal in microfilm/nuclear-plan barter-based processes.</p> <h2>But that’s not really how SSH keys work</h2> <p>No, not really, but close enough. If you squint.</p> <div class="i-fullwidth"><img src="spy-vs-spy.jpg" alt="image" width="700" height="284"></div> <p>Instead of literal private keys and public padlocks, think of public and private SSH keys. Public keys can encrypt a message, and the corresponding private key is the only one that can de-crypt it.</p> <p>When you first connect to a remote machine for the first time, it will send you its public key. If you’ve uploaded your computer’s public key to the server, it will use that to encrypt a message and send to your machine.</p> <p>If your machine can decode that message correctly, that’s half the job done. Next, your machine uses the remote’s public keys to encrypt that message and send it back.</p> <p>If the remote machine can successfully decrypt that message, both machines can be reasonably sure that other can be trusted and get on with the business of transacting.</p> <h2>That was a lot of text. What do I need to <em>do</em>?</h2> <ol> <li>Create a SSH public/private key-pair.</li> <li>Add the public key to the remote server’s ‘trusted keys’ list.</li> <li>SSH to the remote server.</li> <li>Accept the remote server’s public key.</li> </ol> <p>Basically, do the same steps as outlined on <a href="https://help.github.com/articles/generating-ssh-keys">the Github help</a> pages. But now you know more about what is actually going on there – great!</p> <p>Next time we will be doing a lot more of the hands–on work, and should act as the one–stop reference page you actually need to get this SSH stuff done.</p> Cape Town Front End Developer meetup https://richarcher.co.uk/articles/2013-03-14/cape-town-front-end-developer-meetup/ Thu, 14 Mar 2013 19:48:00 GMT rich@richarcher.co.uk (Rich Archer) https://richarcher.co.uk/articles/2013-03-14/cape-town-front-end-developer-meetup/index.html <p>Yesterday I got to give a small presentation at the newly formed <a href="http://www.meetup.com/ctfeds/">Cape Town Front End Developer Meetup</a> about a subject very close to my heart; CSS, or rather modular CSS.</p> <p>Here are the slides:</p> <script async class="speakerdeck-embed" data-id="23f863406f7f01305790123139082352" data-ratio="1.33333333333333" src="//speakerdeck.com/assets/embed.js"></script> <p><a href="https://speakerdeck.com/richarcher/creating-maintainable-css">link to speakerdeck</a></p> <p>It was both terrifying and exiting to give my first technical talk to a room full of experienced and knowledgable peers, and if it’s something you haven’t done yet, I cannot recommend it enough. In the words of the smart chap that convinced me to give it a go: “There’s got to be <em>someone</em> that doesn’t know about this stuff”.</p> <p>Wise words indeed.</p> <p>If you do have any questions about any points raised by the presentation, please don’t hesitate to get in touch with me on Twitter (<a href="http://twitter.com/slocombe">@slocombe</a>) or drop me an email (<a href="mailto:howzit@richarcher.co.uk">howzit@richarcher.co.uk</a>).</p> <p>Also, if you’re in the Cape Town area, please drop by the group sometime – it’s got a fantastic vibe that’s only just started and going to get better.</p> Pointless carousels can burn in hell https://richarcher.co.uk/articles/2013-01-10/pointless-carousels-can-burn-in-hell/ Thu, 10 Jan 2013 13:42:00 GMT rich@richarcher.co.uk (Rich Archer) https://richarcher.co.uk/articles/2013-01-10/pointless-carousels-can-burn-in-hell/index.html <p>A little challenge I set myself when designing a site is the “Don’t use a pointless carousel of images on the front page” game.</p> <p>If I can design a site that is useful to the user across all platforms, conveys the message of the site quickly, converts the user to the purpose of the site easily and doesn’t rely on a constantly changing section of site to fit as much information into already crowded screen real-estate, then <em>I Win</em>. 10 points to Gryffindor and all that.</p> <p>I don’t always manage this, and the plain reality of carousels is that sometimes they <a href="http://bradfrostweb.com/blog/post/the-overflow-pattern/">are very useful indeed</a>. But that doesn’t stop me trying other approaches first.</p> <p>A while ago I was building a small, single purpose site that did one job very well. The copy for the site was short, succinct and to the point. On coming up with a layout, the clients and I were exploring options to give the page a bit more ‘pop’. The consensus was that a carousel was the best thing to use.</p> <p>The first question is “Why”? The second is &quot;What should appear in there?</p> <p>To slap on a rotating image carousel of laughing women eating salad or a racially diverse collection of directors smiling around a boardroom table would do a disservice to a product specifically designed to work without frills.</p> <p>This is something that pretty much all websites must go through – the fear of perceived lack of content or the struggle to organise content into a respectable hierarchy, usually followed by a panicked attempt to “fluff up” the content a bit.</p> <p>Maybe we should have a carousel with each panel sliding in explaining some facet of the product that had not yet been considered by the user? To do the job, in fact, that a single bullet point list could do in a second?</p> <p>Maybe we should use carousels as an interesting way to direct users to other parts of the site that they hadn’t considered before? Yes… a sliding interactive gallery of “<em>Hey guyse we got us some case studies</em>” or “<em>lol! contact us!</em>”.</p> <p>While this approach might work for a while; your dark corner of the site has a tiny torchbeam of recognition shone into its crevice, but what about when you change the carousel to point somewhere else? Are you assuming that all that crazy traffic will somehow be retained? If you’re relying on a carousel to direct users around your site, you’ve bigger problems than what to put on your front page – SEO, IA and frankly, the general usability of the site is brought into question.</p> <p>If we entertain the carousel notion for a little longer, more questions arise – how should this function without javascript enabled? It is to be an infinite carousel or to scroll back to the beginning? If it’s a combination of text and images, is the text separate from the images? Is each panel to be distinct and unique with it’s own ‘feel’? How would one manage the styling of these special little snowflakes? Is it possible to skip panels, is it possible to pause? How do touch screen interfaces work with it? How do skinny viewports interact with it – and is it different to the full-fat equivalents? Scroll left-to-right, top-to-bottom, fade in-out?</p> <p>There’s no such thing as “Just” using a carousel. Unfortunately that’s how they’re treated – a graphical flourish that somehow is meant to bring extra gravitas to a design without much thought as to what they’re actually meant to do.</p> <p>To me, carousels are heading on a course that is sending them very close to the same school-of-design-dustbin in which Comic Sans and Flash splash-screens reside. Needless overuse eventually will make it a reviled option amongst designers and stop people using them when they <em>are</em> a good idea.</p> <h2>(Update 24th Jan) Required reading from far smarter folk</h2> <ul> <li><a href="http://bradfrostweb.com/blog/post/carousels/">Brad Frost wrote a great piece on his thoughts around carousels</a></li> <li><a href="http://weedygarden.net/2013/01/carousel-stats/">Notre Dame university publishes their findings on their effectiveness</a></li> </ul> Flickr's new iOS app made me fall in love with the service again https://richarcher.co.uk/articles/2012-12-19/flickrs-new-ios-app-made-me-fall-in-love-with-the-service-again/ Wed, 19 Dec 2012 09:38:00 GMT rich@richarcher.co.uk (Rich Archer) https://richarcher.co.uk/articles/2012-12-19/flickrs-new-ios-app-made-me-fall-in-love-with-the-service-again/index.html <p>When Flickr released their new app amongst a fanfare of delighted tweets last week, I was, I admit, a little cynical. But the after a few days of usage, I’ll happily put my hands up and admit just how very wrong I was.</p> <p>I didn’t, I admit, use Flickr to it’s full potential. Back in the day I would upload photos of various holidays or parties to the site, and emailed the url of the set to my compadres, and that was really it. Unfortunately, no-one in my social circles really used Flickr, and all (at the time) were all using Facebook.</p> <p>I also used the service as nothing more that an online repository of <a href="http://www.flickr.com/slocombe3000">my various photographic attempts</a>; away from the frailties of my own hard-drives that had failed too many times in the past.</p> <p>Other offline storage options emerged, and when the time came to renew my Pro membership… Well, let’s just say we parted company. In fact, I very nearly closed my account down entirely serveral times - but never <em>quite</em> got around to it.</p> <p>Enter the Mobile Revolution; we’re all on phones now - taking instragraming, tweeting, whatsapping - everything we currently want to do, we can do from our phones.</p> <p>The app capitalises on the amazing success of Instagram and their ilk, working on the axiom that the ‘best camera is the one you have with you’ - usually your iPhone - to capture those occasional moments that should be immortalised and shared amongst your friends. It has the vintage filters, should you need them, plus some additional editing tools, as well as the ability to easily follow your contacts as easily as in Twitter.</p> <p>For me, what’s different this time is that the photos are being saved to a <em>photo</em> service. Not a Facebook timeline or a Tumblog or Twitter stream - a service for storing and keeping your random photos of coffee secure. They feel safer there in a site designed for them exclusively - alongside the photos I may choose to take and upload via my larger cameras, rather than lost amongst the status updated and animated Doctor Who gifs.</p> <p>What really sold me though, was that the app takes the core service of Flickr, and then enhances it with the native app functionality of the camera and editor. This kind of progressive enhancement of a web app with native apps is exactly the sort of setup tht flies my flag. A smashing mobile-optimised web site as a baseline, with all the features available to non-iPhone viewers - with an additional layer of interactivity on the native app with the camera and editor. With the web site in place, the native app pivots incredibly well on the social/sharing side of the service, without excluding anyone who doesn’t have a particular type of smart phone.</p> <p>All in all, the Flickr app is a wonderful layer of app-like beauty draped over an already excellent service that is at a stage in its lifetime where other services would simply have rolled over and died. Flickr has resurrected itself and in turn reinvigorated my love for the place - to the point where I’m most likely going to upgrade my service to Pro status again, no longer for me just a storage option, but somewhere where I can enjoy being part of a community just as much as I do on other sites.</p> <p>I’m probably not going to be the only one either - I’m certain that there are plenty of people just like me that are going back to her, looking sheepish and trotting out a mumbled apology about asking to be let back in again - Instagram was a once-off mistake. We’ll not do it again…</p> That Zuckerberg HTML5 Quote https://richarcher.co.uk/articles/2012-12-03/that-zuckerberg-html5-quote/ Mon, 03 Dec 2012 21:09:00 GMT rich@richarcher.co.uk (Rich Archer) https://richarcher.co.uk/articles/2012-12-03/that-zuckerberg-html5-quote/index.html <p>Misappropriated quotes from billionaire social media tycoons are misappropriated.</p> <blockquote> <p><q>I think the biggest mistake that we made, as a company, is betting too much on HTML5 as opposed to native…</q></p> </blockquote> <p>As part of my research into the native versus cross-platform apps debate, I saw this quote a <em>lot</em>. I understand why; it’s a great quote – even if it’s taken entirely out of context.</p> <p>I was recently invited to participate in a great <a href="http://www.spin.org.za/2012/11/28/spinjam-photos/">meetup</a> at Cape Town SPIN – “Native vs Cross-platform for Mobile Development” (hence my <a href="/blog/2012/11/20/native-vs-cross-platform-for-mobile-development/">previous post</a>).</p> <p>We all know by now about Facebook’s fairly high profile ‘ditching’ of HTML5 in favour of native development. It was hailed as the apparent final nail of the markup coffin, with native apps proving to be the all-conquering hero.</p> <p><em>Okay</em>. To an extent, we HTML5-ers were probably due a little bit of hubris after rubbing Facebook into the collective faces of the web-app dissenters a few years ago. Fair enough.</p> <p>But before someone churns out the quote verbatim again, can we just check our sources a little here?</p> <blockquote> <p><q>When I’m introspective about the last few years I think the biggest mistake that we made, as a company, is betting too much on HTML5 as opposed to native… because it just wasn’t there. And it’s not that HTML5 is bad. I’m actually, on long-term, really excited about it. One of the things that’s interesting is we actually have more people on a daily basis using mobile Web Facebook than we have using our iOS or Android apps combined. So mobile Web is a big thing for us.</q> <cite>Mark Zuckerberg @<a href="http://techcrunch.com/2012/09/11/mark-zuckerberg-our-biggest-mistake-with-mobile-was-betting-too-much-on-html5/">Disrupt SF 2012</a></cite></p> </blockquote> <p>Context is always important.</p> Native vs Cross-platform for mobile development https://richarcher.co.uk/articles/2012-11-20/native-vs-cross-platform-for-mobile-development/ Tue, 20 Nov 2012 17:01:00 GMT rich@richarcher.co.uk (Rich Archer) https://richarcher.co.uk/articles/2012-11-20/native-vs-cross-platform-for-mobile-development/index.html <p>I don’t have a problem with native mobile apps. In fact, I love them. But then again, I’m an iPhone owner. We get all the cool stuff.</p> <p>Apps can be wonderful if you have access to them. But if you are not one of the blessed few that has a device with a matching app, where does that leave you? Forced to use an actual… *gulp* <em>website</em>?</p> <p>In South Africa in May, there are 8 million mobile-web users out there, the top 3 platforms being used on the day of writing being Symbian, Android and the Nokia Series 40, each with approximately 22% of the market.</p> <p>Not quite so shortly behind them are iOS (iPad, iPhone, iPod Touch), “Unknown”, Blackberry, Samsung, the mysterious “Other”, and Windows Phone.</p> <p>Even if we elected to develop only for a small portion of these phones, there would be a costly amount of developer time needed to develop (and maintain) specific apps for each. And how do you choose which one to develop for?</p> <blockquote> <p><q>Oh! If only there was some sort of standardised markup language that would be understandable by anyone with web connection</q> <cite>– Sarcastic Greek Chorus</cite></p> </blockquote> <p>Does your phone have a browser? Boom! Instant access to your web-app by potentially hundreds of thousands of users.</p> <p>Developing a web app is faster and easier to develop for, easier to iterate upon with feature releases and is truly the “create once, publish everywhere” environment. In short; less cost across the board.</p> <p>As a web-app, it is possible to leverage the basic nature of the web; it will instantly be more ‘findable’ on the web as opposed to being lost amongst hundreds of similar apps in an app store somewhere, as well as being easily linked to and shared in Twitter, Facebook, LinkedIn or any other site.</p> <p>As a web-app, your service remains unencumbered by the slings and arrows of a 3rd party app store. By developing a web app, you are avoiding having a cut of any revenue made from within the app being taken by the app store, such as the <a href="http://www.guardian.co.uk/media/appsblog/2012/apr/24/financial-times-web-app-2m">Financial Times</a> chose to do when Apple wanted a cut of their users’ subscription fees.</p> <p>As a web app, if you need to redeploy your app after a minor release, you are not penalising your user’s bandwidth caps by forcing them to re-download a 10MB binary for a small tweak.</p> <p>As a web app, if a new web-enabled device arrived on the market, we know that device will be able to access your app already without any delay. Your app is <a href="http://futurefriend.ly/">Future Friendly</a>.</p> <p>There are differences between devices. All devices render differently, and on different screen sizes and resolutions. Fortunately, dealing with an uneven playing field is what us front-end developers have been doing for years; by embracing the principles of accessibility, graceful degradation, feature detection and adaptive design, we have been creating web pages that take advantage of newer technologies as they are made available to us, whilst allowing the web experience to fallback to a more basic interface for the older browsers.</p> <p>You are not preventing any users from accessing your content, and you are not penalising the newer users by catering soley to the lowest common denominator.</p> <h2>A dash of reality</h2> <p>As much as I would love to hitch up the HTML5 wagon and ride off into the sunset, the simple facts of the matter are that some people EXPECT a native app of some sort. The simple fact is that native apps are in the main faster AND they can <em>currently</em> do more than traditional HTML5 apps. iOS users expect a higher polish to their app experience, <a href="http://blog.mobtest.com/2012/05/heres-why-the-facebook-ios-app-is-so-bad-uiwebviews-and-no-nitro/">and will freak the hell out if that experience does not match their expectation</a>.</p> <p>Put simply, it’s a case of comparing the <strong>richness of native apps</strong> against the pure magnificent <strong>reach of HTML5</strong>.</p> <p>Trying to replicate an native app experience in a HTML environment is setting yourself up for a fall. People will inevitably make comparisons and at some point they will notice that there is an <a href="http://en.wikipedia.org/wiki/Uncanny_valley">uncanny valley</a> effect, in which the web app will come out the loser.</p> <p>But that doesn’t mean that you should go racing ahead and develop a native app straight away. Don’t instantly reduce your market by developing for a specific platform.</p> <h2>Start wide and then focus in</h2> <p>Here is what I would suggest. Develop your web-app first, quickly, publish, get it out there. <a href="http://en.wikipedia.org/wiki/Minimum_viable_product">Minimum Viable Product</a>. Iterate. Learn from your users. Develop your brand. A/B test. If there is a need for a native app after that and you have the resources, you are better positioned to take the lessons from your website and improve them in the app.</p> <h2>Native development as a form of progressive enhancement</h2> <p>Here’s what you gain from this approach:</p> <ul> <li>You know which segments of your potential market you are missing out on entirely, or which segments of your market you want to capitalise upon.</li> <li>You “<a href="http://designingsocialinterfaces.com/patterns/Pave_the_Cowpaths">pave the cowpaths</a>” – watch the interaction patterns your users navigate the site and enhance them in the app. Not sure which platform to develop for first? You do now.</li> <li>Less waste of expensive native development time trying to position your app correctly within the market.</li> <li>Less chance of annoying your userbase with an ineffective app.</li> </ul> <p>In summary, there’s no reason why native and web apps need be in direct competition; they can exist perfectly well together.</p> <p>But seriously. Do the web app first.</p>