What we would change about Rizzo

I've heard recently that a few different companies have created a version of Rizzo to build on the work we have done at Lonely Planet. It's extremely flattering to hear about our ideas helping other organisations. It also makes me a little nervous because if someone were to copy Rizzo as it exists now they would inherit some of the decisions which ultimately we would change in hindsight (and plan on doing in the future). This article outlines some of those decisions and how we would approach them differently.

I should mention that the fundamental principles behind Rizzo as a component library and Maintainable Style Guide still stand true and those haven't changed since its inception. That said, there are definitely certain decisions which I would love to have the opportunity to revisit and which I would advise anyone starting down this path to consider.

1. Fix up your filesystem structure

Grouping files together by component makes it considerably easier for developers to find files and makes the boundaries of the component clearer.

// The old way

app/
  data/
    header.yml
  javascript/
    header.js
  stylesheets/
    header.css
  views/
    header.html
// A better way

app/
  components/
    header/
      header.css
      header.html
      header.js
      header.yml


We inherited Rails' directory structure which organises assets by file type and this is also a long running convention used in many frameworks including the html5 boilerplate. Despite this, it doesn't make any sense to continue organising files by their file type and this is a best practice which should definitely be challenged.

In the example above, header.yml would include stubbed data used to render the component in the Style Guide.

Using this form of filesystem convention also greatly simplifies point 2.

2. Let the component manage its own assets

As soon as you get on board with the idea of components you realise it makes no sense for a ‘page’ to define the dependencies of the components it will render. A page should have no knowledge, nor care, which components are used to construct itself. Even so, this is still typically how we manage assets: using an application level manifest file which imports the dependencies for each component. Think of any classic application.sass which imports all the partials for that page for example.

The main area in which the old technique falls down is when you begin lazy-loading in components. Keeping stock of which components will be loaded into the page template creates a very brittle system and it makes much more sense to let the component fetch its own dependencies, teardown and initialise itself.

Of course this isn’t without its own challenges. You still need to architect a system whereby lazy-loaded components can be instantiated and you must also consider how to bundle dependencies by page, or ‘entry point’. Fortunately there are a collection of tools which are designed to help you with the latter process - Webpack, assetgraph, jspm, browserify to name a few.

3. Use a language agnostic templating syntax

A misconception of Rizzo is that it is limited to the stack we wrote it on (Ruby). This is somewhat true as the components are primarily written in Haml, which is tightly coupled to Ruby. We do also expose certain components via http endpoints and send them over the wire, making them accessible from any stack.

What is definitely true, however, is that had we chosen Mustache or another language-agnostic templating language we would have created a more flexible system to work with and reduced the number of hoops we inevitably have to jump through when using Rizzo on different stacks. This also has the advantage of making them available to the client without the need for writing any adaptors.

4. Deploy updates automatically across applications

We deploy Rizzo as a gem within each of our applications. A consequence of this is that we need to explicitly bump the Rizzo dependency in each app after we make an update to a component (in practice this happens organically unless it’s a significant change). This is a safe way of managing our components but as we've scaled up the number of applications it is becoming more tedious.

Rizzo serves some components (header, footer) over http to our legacy apps. In this method, the changes are updated automatically as soon as we deploy Rizzo. This removes any update process entirely but does introduce a risk that we could break these applications (which of course we have, on occasion). This doesn't fit in to our model of continuous delivery at Lonely Planet and is not something we would rush to do on a broader scale, however GOV.UK have recently written about their implementation which does follow this pattern. It's an exciting project (and awesome that such a project has taken something from our work) and I look forward to seeing how that evolves. Given the smart engineers over there I’m sure they have something in place to de-risk the process.

I hope we at some point look into updating Rizzo automatically across our apps at Lonely Planet. I would still prefer us to keep the same system of being declarative about specific dependencies and ensuring that we run the full suite of tests for each application. Either way, you have a set of trade-offs to balance.

My ideal process would be to have a post-deploy hook on Rizzo that triggers builds of all applications that use it and, if successful, deploys them. This would create a lot of noise in our CI environment though, and would need to be thought through a lot more before we actively pursued it. Likely this solution will wait until the current process gets too painful to support.

Are you using a component API like Rizzo?

If so I’d be keen to hear about it! Have you made any changes similar to the above which others could learn from?

CSS at Lonely Planet

Inspired by Mark Otto's post Github's CSS I thought I would quickly jot down how Lonely Planet’s CSS is structured. I thought it was interesting to read some of the parallels and it’s good to share how we work.

Quick Facts

  • We write in Sass (Indented syntax).
  • We have more than 150 source files.
  • The compiled CSS is split into two stylesheets to allow for stronger caching across apps.
  • The average weight of CSS per page is around 35kb (gzipped).
  • Rems and pixels are the unit of choice, with scattered ems.

Preprocessor

When I joined Lonely Planet we were already using the indented Sass syntax and have stuck with it since. Having used it for so long, writing SCSS seems like a chore.

Whilst we use Rails, we compile our Sass without Sprockets and just use Sass’s @import functionality to build up stylesheets.

Our use of Sass’s features is pretty low, mostly limited to variables and a few mixins. We originally started out with an architecture favouring extending placeholders over classes in the dom though this gradually caused our codebase to become too complex and we reverted our course to a more OOCSS approach.

We use autoprefixer to handle vendor prefixes and I encourage everyone to do the same. We don't use Compass or any other plugins.

Architecture

  • We use a version of BEM to distinguish between components and prevent style collisions.
  • We take a rough approach towards OOCSS. We started out with good intentions there but haven't stuck to it religiously.
  • We don't use IDs in CSS. We very rarely style anything but classes.
  • We use normalize.css.
  • We avoid styling elements and scope all our typographic styles to classes. Typographic elements don't get margins by default as it leads to too much overriding (in our design).

Frameworks

We don't use any CSS frameworks. If we were to begin again I would be tempted to use something like Inuit.css although ultimately I like the fact that we have no dependencies and are in complete control of our CSS.

Linting

We don't lint our CSS. It’s something that we should look into.

Bundles

Our CSS is distributed in two files:

  • core.css
  • application.css

Core is cached across the entirety of lonelyplanet.com whereas application.css is cached only within the specific application. Lonely Planet is served by more than 10 distinct applications so having this separation is crucial for us to render faster pages.

Core includes the base styles like fonts, grids and header/footer styles, and also includes some of our most commonly included component styles which we choose to cache across all the apps. These components and styles live in Rizzo which is accessible by all apps.

Application.css will include styles distinct to the specific application, as well as some Rizzo components which aren't used often enough to be included in core.css.

Performance

The above bundling is key to our CSS performance as is keeping the files small themselves. We have a performance monitoring section in Rizzo which trends file size changes. Currently it only trends for seven days as this is a new addition to Rizzo and we are still collecting data.

CSS Performance Trending

We collect this data every few hours using a few simple scripts which also allows us to run analysis on the stylesheets. We do this with Stylestats and again render the breakdown in Rizzo.

CSS Analysis

Documentation

I've written previously about our Maintainable Style Guide, Rizzo and it works very successfully.

We also self document our Sass by wrapping it in [doc]..[/doc] tags, and then statically analysing it. For example, this utility_classes.sass file creates this documentation in Rizzo.

CSS Documentation

Refactoring

Similarly to github, we like to get rid of as much code as we can and we’re not precious about keeping things around in case it might be needed. Refactoring is a part of our daily work though and we very rarely have specific refactoring tasks.

Other CSS Files

Our SVG icons and fonts are both loaded within CSS files, but these are deferred and not grouped with the rest of the styles.

A Maintainable Style Guide

Anyone who has attempted to maintain a UI Style Guide over a long period of time will attest that it is a very difficult process. They are generally prioritised below the maintenance of your applications themselves and as such are likely the first candidates to fall behind and the last to be brought out of tech debt.

This is bad because once your Style Guide falls out of sync with your application(s) it has entirely lost its purpose. It is no longer a trustworthy representation of the state of your UI and will quickly fall out of favour with the design and development team.

This is bad because Style Guides are more than a nicety for developers to show off their style. Done properly, they can be a collaboration tool bridging design and development teams as well as a tool to break down the user interface into its component parts rather than than thinking about it as a whole or as a series of pages. They also serve as a resource for new designers and developers to locate existing patterns for further use.

These benefits should be sought regardless of the size or scope of your project but in order to achieve them they can’t come at a cost to delivering features. If they do, they will inevitably be neglected.

Achieving this is a cultural challenge as well as a technological one. At Lonely Planet we managed to accomplish this by making the Style Guide an integral part of our development workflow.

This didn’t happen easily though, before we found success with our latest attempt we had tried and failed with two earlier approaches and unearthed problems that helped us mould our final solution.

The problem with current Style Guide Solutions

A Static HTML Style Guide

Style Guides built with static HTML are standalone representations of your UI components with no direct link to your codebase. Once you change or refactor your HTML or CSS you need to update the Style Guide if you want it to reflect the latest version.

The main difficulty with keeping this up to date with your application is having to update both versions of the same template. It requires diligence on the part of all developers to manually keep it up to date.

I built a static html Style Guide a couple of years ago to try to decipher the UI we had inherited. It gave me some clarity on our UI but didn’t fit into our workflow and ultimately didn’t make our work any easier. It quickly became a burden to maintain and fell behind and out of importance.

It’s worth mentioning that as a design tool, or as a deliverable to a client who is going to carry on the development, static Style Guides are a fantastic starting point.

A Living Style Guide

Living Style Guides should be the answer to these problems. They autogenerate Style Guides when changes are made to the codebase so in theory they shouldn’t be able to fall behind. There are a whole host to choose from and many can be set up with fairly minimal effort.

Back in 2012 we implemented KSS a fairly popular tool for generating living Style Guides developed by Kyle Neath and used at Github. Unfortunately, it only lasted 2-3 months before it was clear it had diverged from the components within our application.

So, given it’s “living”, why did it fall behind?

The majority of living Style Guide generators work by analysing the CSS: parsing comments within the files to create the documentation and to know which components to render. It makes sense that they would take this approach because CSS is easily analysed and consistent across projects. For a generic library to work across multiple applications it requires a constant to work from but it’s this key design decision which ultimately makes them hard to maintain.

There are a couple of significant ways in which we believe this type of Style Guide is unmaintainable:

1. Duplication of templates

The majority of living Style Guide solutions follow a pattern something like this:

  /* Style Guide [Buttons]
    <button class="btn-primary">Button</button>
    <button class="btn-secondary">Button</button>
  */

  .btn-primary {
    color: blue;
  }

  .btn-secondary {
    color: red;
  }

Here we have a couple of buttons referenced in the CSS which are rendered in the Style Guide as both elements and markup.

The problem here is that the template we render in the Style Guide isn’t the template we use in our applications. At best it is a direct copy; more likely it is a slimmed down, and perhaps out of date, copy.

As soon as you introduce template duplication like this you have twice as much to maintain. Inevitably, for a project spanning even just a short time, one of them is going to falling behind.

Now this is easy to overlook when you’re talking about single element components like buttons where the effort is fairly minimal to maintain but in reality a lot of components are more complex: requiring multiple elements, classes and often Javascript. We should be striving for a solution which sticks as close as possible to production.

2. Static HTML Output

There is also the problem of the output. Typically you would feature the component alongside the markup required to render it:

Markup commented within the CSS
(taken from the excellent Mailchimp Style Guide)

The idea here is that a developer can simply copy and paste this markup into their application and very quickly and easily build up their page from component parts.

Whilst this is an excellent goal, the problem in this case is the distribution of templates. Even if we presume that the rendered markup is absolutely up to date, once they copy that code they are essentially cutting a version which needs to be maintained indefinitely. When they copied the markup for a working component it had an implicit link to a snapshot of the CSS at that point. If you then update the template or refactor the CSS, you need to update all versions of the template scattered around your site.

This posed a huge problem for us because authors of components had no idea of where they were being used. They may not even have heard of the application that is now using it. That increases the risk of releasing a breaking which makes it more likely that future developers will avoid updating and reusing the component at all.

This is a huge cause for Technical Debt build up at Lonely Planet. As the entire infrastructure is too large to completely hold inside your head, authors were being forced to build defensively. As there was no mechanism for encouraging risk-free reuse of components, they simply weren’t being reused and we instead ended up with duplicated components and bloated code.

I don’t believe this is an issue scoped only to Lonely Planet or even limited to just large websites. Reducing the distribution of templates promotes easier, risk-free refactoring regardless of the size of complexity of a website.

How should Style Guides work?

They should focus on the templates. Crucially, if you’re rendering templates to a Style Guide and you want it to be maintainable then they can’t just be identical to your application templates, they need to be the exact same templates. This is easier said than done.

Templates within an application can be written in many different languages and are generally coupled to a data layer, embedded deep into an application and hard to get to. This makes it very hard for a single Open Source tool to parse your templates. It would have to work across a multitude of technologies and disparate application architectures.

This doesn’t mean it’s impossible to achieve. It does require your application to be built in a modular, component driven way though. Isolating parts of your UI into small components allows you to reuse them around the site as well as compose them to create greater functionality.

Within this type of architecture the Style Guide is able to reach the same components without understanding your entire application. To achieve this can involve a decent chunk of work although the process of restructuring your application into a component based architecture can be the mechanism to simplify and normalise the UI: bringing benefits far beyond the Style Guide itself.

This is the process we have taken at Lonely Planet, creating a component layer which both our user-facing applications and our Style Guide can work from.

Building a Component API

Slides from "Reducing Complexity with a Component API"

I go into more detail on the reasoning behind this process in my Front End Ops talk. The process of decoupling the User Interface from the application, and splitting them into components, had a lot of positive effects on our workflow and codebase.

The goals and benefits of a Style Guide were exactly what we wanted but, not knowing how to achieve them, we started by extracting as much of our UI into components and moving them outside of the applications. This also gave us the opportunity to normalise and condense our UI. Once done, we created a very simple API in which to fetch them from the Component Layer. Having the api for us was crucial because we wanted to maintain the mapping between the latest version of the the component and the application, and not have developers copy and paste component code.

Having a single version of the component, accessible via an API, worked perfectly with unit testing too so we could ensure that the contract between the API parameters and the returned template was solid. We could modify and extend the component based on the data we passed it and assert on the returned result. This also allowed us to add accessibility helpers and microformat attributes as standard and ensure that they weren’t forgotten when used in new applications.

A typical API call:


  // Input
  = ui_component("forms/search", {label: "Search"})

  // Output
  <form class="search--primary" action="//www.lonelyplanet.com/search">
    <label class="accessibility" for="search-q">Search</label>
    <input class="search__input" id="search-q" name="q" tabindex="1" type="search" value="" />
    <button class="search__button" id="search-q-submit" name="search-q-submit" type="submit">Search</button>
  </form>

The developer can modify and extend the component by manipulating the input data. For example, if we wanted to add autocomplete functionality to this search form we would usually do so by adding classes and maybe initialise a JS component somewhere. Within the scope of the Component API we can simply pass in a new boolean and it will add what is necessary:


  // Input
  = ui_component("forms/search", {
    label: "Search",
    autocomplete: true
  })

  // Output
  <form class="search--primary js-autocomplete" action="//www.lonelyplanet.com/search">
    <label class="accessibility" for="search-q">Search</label>
    <input class="js-autocomplete-input search__input" id="search-q" name="q" tabindex="1" type="search" value="" />
    <button class="search__button" id="search-q-submit" name="search-q-submit" type="submit">Search</button>
    <div class="js-autocomplete-container"></div>
  </form>

Style Guide Driven Development

Once the API is being used to fetch components, all that we really have inside any application are data representations of the components. It’s therefore pretty simple to scaffold a quick application that requests every component, multiple times, with differing data. This becomes our Style Guide. Where a regular application might request a handful of components, the Style Guide requests every component, again and again.

It’s always up to date with the rest of lonelyplanet.com because it uses the exact same templates and CSS. As we’re not just performing static analysis of the CSS we are also able to showcase components that require JS too. It becomes a risk free environment where developers can build and tweak components and then allow them to propagate out to the rest of the applications.

In fact, it has become the primary arena for development. Once you have this concept of a component layer it is irrelevant to a developer where they render it for testing. What we have seen is an organic move towards Style Guide Driven Development where developers are using it to build and iterate on components long before they reach any application. This is not something we expected but is certainly a validation of the approach and a polar opposite to our previous attempts where the Style Guide was seen as a blocker to quick feature development.

An example of our Style Guide output
An example component in our Style Guide would showcase the component alongside the API call with data.

How it all works

Our Component Layer, API and Style Guide are combined into an application called Rizzo. The Style Guide is available at rizzo.lonelyplanet.com. One thing I really didn’t cover in my talk at Front End Ops Conf was the implementation side of Rizzo and I’ve had a lot of questions around it since.

We have two different categories of apps that integrate with Rizzo at LP: Rails Apps and Other Apps.

Rails Apps

Rizzo is included as a Gem within all our applications and acts as an engine, thus exposing its partials and assets to the host App. The implementation of the API here is extremely simple and is really just sugar coating around a partial call. The only part that makes this different to just calling a partial is that it lives outside of, and is shareable across, all applications. These helpers act as the API for the Style Guide and the applications.


  -# Called from an application
  def ui_component(type, properties)
    render "components/#{type}", properties
  end

  -# Called from the Style Guide
  def styleguide_component(type, properties)
    ui_component "components/#{type}", properties
    render "styleguide/description", type, properties
  end

There is a little bit more to it but that covers most of how it works. Very, very simple. It’s much more a methodology change than it is a technical challenge.

Other Apps

Non-ruby apps don’t have the luxury of including Rizzo as a Gem (though we may look into using it with other package managers). For now, we host Rizzo as a service and expose HTTP endpoints to return the templates. For example, hitting http://rizzo.lonelyplanet.com/global-body-header will return the html for part of our header.

This adds an extra layer of complexity for these applications as they then have to implement a caching layer for Rizzo components. We cache these templates when the application boots. It’s not perfect but given our primary stack is Rails it’s not something we have spent too much time on yet.

The Style Guide

Once you have a component architecture your Style Guide can simply be another application. Ours is a tiny Ruby app, but you could use absolutely any technology including a simple static site generator.

The Style Guide simply loads up some data for a particular type of component and then iterates through it: rendering the component and the component description each time. Note it’s calling styleguide_component which ultimately calls ui_component the same as any other application would.


-# Load the data
- cards = YAML.load(File.read(File.expand_path('data/styleguide/cards_stubs.yml', __FILE__)))

<h1>Cards</h1>

-# Iterate through the data collection and render the components
- cards.each do |card|
  = styleguide_component("cards/#{card[:title]}", properties: card)

With this approach we only have to modify the underlying data to add more components or modify existing ones.

Assets

A common question has been how do we handle CSS and JS related to these components. Unfortunately I don’t have a clever answer for this at the moment, it’s a mostly manual process.

We split both our CSS and JS out into common and application files. Inside the common.css|js we load the base code as well as our most often used components (stored in /components/core). This is then cached across the entire suite of applications.

To use any non-core components within an application the developer would need to import the component’s related assets using Sass and requireJS.

I think there is definitely room to improve this process using tools like Component or AssetGraph and it’s something we’ll be looking into soon. For the moment, it is reasonably trivial to handle manually.

Rizzo on GitHub

The source code behind Lonely Planet’s components is now public at https://github.com/lonelyplanet/rizzo. The implementation is very bespoke to Lonely Planet but should give some indication of how our architecture works if you are interested in taking a similar approach. Here are a few example pieces that make up Rizzo:

A component template

A component Stylesheet

API Helper

Style Guide Data

Style Guide View

Conclusion

I believe that the difference between Rizzo and our previous two Style Guides, in terms of their successfulness, is that with Rizzo we didn’t focus on the Style Guide as the deliverable. Instead we focused on reducing complexity and increasing reusability. The Style Guide was then simple to add on at the end but, had it not been, we would still have been in a better place regardless.

To achieve something like this you’re never going to be able to just run a grunt task and have it happen for you. Unfortunately it’s not something you can add on at the end, though nor should it be. It requires you to contemplate your site architecture and structure as the main focus and the benefits of that can then extend far beyond a Style Guide.

At Lonely Planet we have a long way to go to create a solid, consistent platform, but this has certainly been proven as a step in the right direction. If you are starting a new project, or you have the means to invest some time in maintainability, I would thoroughly recommend a component based architecture along these lines.