Our HTML prototyping process
In 2013, we started to look at the benefits of building a maintainable component library and how we could use it for the City of Gothenburg’s external and internal web applications.
The primary goal was to:
- Increase the quality and consistency of the user interface across applications and digital web channels.
In this post I’ll share another positive effect – how it has affected and sped up they way we work with HTML prototypes.
Since many years now, we have almost exclusively used HTML prototypes in the development cycle of a project and it has generally worked really well but one problem is that we sometimes, too early in the design process, spend too much on time on details of a design.
With wireframes, a low fidelity design tool, it’s easy to keep focus on the overall page layout, the priorities between information and available functions. Unfortunately, it is not always the best deliverable to communicate concept and design to a customer. Also, wireframes can be difficult to perform more advanced usability tests on.
Moving from a wireframe to a more high fidelity HTML prototype, we’ve seen that it was sometimes easy to instead switch focus toward the details of the specific design. If this was done early in the design life cycle, chances were, that much of the HTML and CSS needed to be thrown out due to changes in requirements or priorities. Fixing details of a design that never reaches production is not time and money well spent.
Another time consuming task has been to keep our prototypes up to date with production code. Especially in the transition phase from the first prototype to an actual implementation when it is likely that many changes will occur and the two processes run parallel with each other.
Three key factors that changed our prototyping process
Three key factors that, in a positive way, have changed the way we work with HTML prototypes are:
- A flexible grid system
- A component library and a design systems thinking
- Component templates
Let’s look at each of them in more detail and see how they have helped us speed up and streamline our prototyping process.
A flexible grid system
Our component library includes a grid component that we use to arrange our components in the larger page regions defined by the overall page layout.
The grid component is called Cell and our grid system uses the Flexbox layout mode. Currently, the most used attributes for the Cell component is size, order and collapse.
The size attribute is used to define different column sizes for different viewports, the order attribute let’s you change order of flex items inside their flex container and collapse removes the default padding of 12 px. This is useful if you have nested Cells and want to avoid padding on each level.
Below is a simple example with a Cell nested inside another Cell. The outer Cell has collapsed padding and an order attribute that changes the source order on mobile-viewports.
Cell — Template markup in XML
<!-- XML -->
<gbg:cell size=”4/4 tablet:4/8 desktop:8/12" order="2 tablet:1 desktop:1" collapse="true">
<gbg:cell size="4/4 tablet:4/4 desktop:8/8">
A nested cell
Cell— Rendered HTML
<!-- Rendered HTML -->
<div data-size="4/4 tablet:4/8 desktop:8/12" data-order="1 tablet:2 desktop:2" data-name="cell" class="c-cell c-cell--collapse">
<div data-size="4/4 tablet:4/4 desktop:8/8" data-order="2 tablet:1 desktop:1" data-name="cell" class="c-cell">
A nested cell
By changing the value of the size attribute you can quickly try out different layouts for different viewports. We think that the column based values for each viewport makes the grid system easy to understand and makes it easy to anticipate the effect of changes.
Having said that, our grid component isn’t by any means perfect. We constantly have discussions about whether we should allow a more detailed control over each Cell and its properties, specifically a more granular way of adding/removing padding around a Cell.
I can see that we, in the future, have to add support for more Flexbox properties. The reason we haven’t done this already is that we, in the beginning, wanted to keep the grid component as simple as possible to avoid having too many different grid settings scattered across our applications.
A component library and a design system mindset
Our component library gives us a pre-defined set of components to work with. We don’t have to spend time reinventing the wheel for design problems already solved by existing components.
Instead of spending time discussing and fixing details of a design, we can use that time to talk about the requirements of an application and if the current set of library components can fulfill them. Maybe an existing component needs to be modified or maybe there is a genuine need to introduce a new component in the library.
The library is currently relatively immature so we are continuously having these discussions. Although this is both a difficult and time consuming task, the result of such discussions can be implemented in the component library and thus still makes it more effective than solving design problems ad hoc for each new applications.
Our component templates, which add an abstraction layer on top of our components, further facilitates this iterative process since changes in markup for a component only need to be updated in one place, i.e. in the template itself.
A developer can see the available library components in our style guide together with documentation on how to use them.
The style guide will be essential to be able to understand our design system and use it effectively in the prototyping process. We still have a lot of work to do in this area and we are currently discussing the different sections and target audiences of our style guide.
As of now, the the style guide only includes examples and documentation of our component library templates.
The component templates are our solution to a maintainable component library. The templates allow us to remove all HTML markup from the applications, only keeping a representation of the content model, the specific data and any settings/attributes.
In the last blog post Dissecting the Slideshow component we took a detailed look at this but below is a simple example of our card component, first the template markup, which is written in XML, and then the rendered HTML.
Card — Template markup
<!-- Simple card using the XML component templates -->
<gbg:element name="header">Meet the gorillas</gbg:element
Meet and feed the gorillas at Nebraska Zoo this weekend.
Card — Rendered HTML:
<!-- Rendered HTML -->
<article data-name="card" class="c-card">
<a class="c-card__title-link" href="#">Meet the gorillas
<svg role="presentation" class="c-icon" aria-hidden="true"><use xlink:href="/img/ui-framework/sprite.symbol.svg#arrow-right"></use>
<p>Meet and feed the gorillas at Nebraska Zoo this weekend.</p>
It was a requirement that the templates also worked outside of our production Java environment, e.g. in our prototype environment which runs on PHP.
This is essential for us as it enables a smooth transition from an HTML prototype to an actual implementation.
Before, the HTML prototypes were yet another artifact that we had to keep updated. This was especially difficult once we started the implementation of a design, then changes were often made directly in the application with the risk of leaving the HTML prototype behind.
Now, the front-end developers have a set of page templates and layouts that correspond to the technical architecture of our IBM WebSphere portal platform. They then use the same template components as we use in our production environment to build the interface.
If we want to keep the prototypes up to date we still need to do some syncing of markup but it is now easier than before. After we leave the initial prototyping phase it is sometimes not even needed since changes are now are more high level and can be communicated directly to the backend developer.
To facilitate the move from a prototype to an actual application we have developed a small browser “inspector” tool which let’s a developer easily switch between viewing the XML-template markup (before transformation) and the transformed and rendered HTML markup. This can be done both in the prototype and in our development environment.
This is useful when you copy code from the prototypes into our applications but also to trace the rendered HTML back to our component templates.
To summarize, I can say that we are happy to see that our design system and component templates also have improved the process of working with HTML prototypes.
If it is easy to build, test and compare different designs, it is more likely that you will actually do that, which in turn probably means that you will get a better end result.
This was part 5 in the publication: Our Story: Building a component library