Designing a style guide & prototyping toolkit with Google Polymer
I recently went through the process of making an element guide and wanted it to be something more. Step in Polymer.
I was working on a design project that involved moving 50 staff facing native apps from one old device to a new one. They were being built offshore, with all of the documentation that requires — wireframes, visual designs — all the artifacts I as a designer hate to make and maintain. Imagine doing that for 50 Apps — no source control, no version control, no change logs. Sketch is great and all, but managing either a huge file or a huge bunch of files became impractical very quickly. After some rounds of user testing, we might find we needed to change one of the key design elements, and I couldn’t stand the thought of editing that many binary files.
Deciding on a solution
My first step was to make an atomic element guide. I needed it to be visually accurate, responsive and flexible to change, so for me, choosing to design in html/css was an easy decision. You can get something on screen very quickly, the structure is simple, there are millions of frameworks, and it’s relatively easy for others to pick up.
I was on the point of effectively making a custom bootstrap theme when I realised I could knock off another key problem I was having. I’m always trying to democratise the design process and I wanted to be more collaborative with development teams, product owners and researchers. There are 50 apps now, but what about future apps?
Wouldn’t it be great if anyone on the team could in minutes spin up a working prototype of their idea that perfectly adhered to the design patterns set out in the element guide?
Wireframe == Prototype == UI Design
I had only recently been introduced to Web Components. Web components are micro self contained blocks of html, css and JS that you ‘expose’ with what is effectively a front-end API. Using web components you can abstract away a lot of the tough markup and interaction design choices from whoever is writing the front end.
Using web components I could build ‘living’ wireframes with native interaction patterns that would always be kept up to date with the style guide. The documentation could, in effect, become the product.
I decided to use Polymer, which is built on top of web components and (despite a few idiosyncrasies) does a lot of the heavy lifting for you.
I have ended up with a solution where I can design and build a new fully functional app prototype in about 15 minutes without ever opening a design application. If I need a new component that doesn’t already exist, that’s fine. Because the components are completely encapsulated I can add new ones without ever having to worry about compatibility with older ones. If it turns out that I need to add more flexibility to an older component that’s fine as well. If in a months time we decide to change the size of our main headings, it’s one change in one place, and all of the prototypes are updated.
Building (and iterating) front end API
If I wanted people to use this system, the exposed API was going to have to be simple, consistent and readable.
I wanted all of my ‘end points’ to be fixed at the point of launch — If someone adds a segmented control in V1 of the library, I wanted the markup to not break when the library is on V2 a few weeks down the line. This has inherently added complexity in the component layer, but that’s complexity I don’t mind; it’s a prototyping tool after all, not production code. If I want to add to the flexibility of an older component, I might up with with some slightly fussy code, but whoever is making the prototype doesn’t have to care.
I designed it for an audience that doesn’t necessarily know html, and I wanted to take as many ‘choices’ out of their hands as possible. To facilitate that, every single element in the front end is a special component. No one ever has to decide between an H2 and H3 or when to use a ul or ol. I decided to expose most of the customisable fields using sensibly named and consistent attributes — ‘title’ for the main text in a component, ‘subtitle’ for secondary text etc.
This reduced the complexity and chances of something going wrong from this:
Admittedly, there is still a learning curve, but it has abstracted away all of the real complexity in the first example. Whoever is making the prototype doesn’t have to worry about styling the table elements, missing closing tags or any of the real semantics.
I also added helper Boolean attributes to every element to do basic styling alteration. There are fixed settings for top margins, centring, indenting and so on. These are set globally and also can be overridden on a per component level which means that while offering some flexibility I managed to stay in total control of the visual output. When working with a team of designers and an offshore development team building to spec, having accurate to the pixel consistency has saved lots of time.
Choosing what makes a component
Deciding the level of granularity that would be useful to someone putting an ‘app’ together was one of the hardest parts of the project. I followed a pretty simple rule: the bigger a component and the more customisation that was needed to make it useful, the more likely I was to split it out into smaller components. If it ever felt like I was abusing an attribute (passing nested arrays and objects as attribute strings in html anyone?) then again, I knew it was time for more separation.
Code duplication is a much smaller problem to me than code dependencies. As soon as one component relied on the existence of another, again I would split them out.
In practical terms, yes, it means that there are a lot of components to choose from when making an application, but it also makes each one far easier to read and understand.
I realised if I wanted people from all walks of life to use my kit then I was going to have to have the most lightweight build and deploy process I could possibly have, but if I wanted these components to be able to change over time, I was still going to need at least some build process.
In the end, I settled upon having a Git repo for every prototype, cloned from a well documented starter kit. Then, using bower, the web component library is could be kept up to date in every local repo. Everything is then just served using Python Simple Server and effectively ftp hosted. It’s basic, but it works — keeping the barrier to entry low was my main priority.
Being able to have prototypes in front of our users that are visually consistent in such short spaces of time has hugely reduced the time needed to iterate. Because each app is so easy to make and so easy to change, I have found myself far less attached to my ideas and far more open to feedback. The up-front cost of designing in this way has paid dividends in both the quality of the work and also in my personal sanity.