This is a tutorial that walks you through the steps needed to move from a static composition to a data-driven prototype, and a living style guide.
After a ramble about the benefits of designing in the browser, and how to choose what tools to use, I walk through a practical step-by-step example of an simple web app to find nearby cafes built using the Vue.js framework, and using a fieldbook.com spreadsheet as the source of data.
This is a looooooong post, if you only have a couple minutes I’d recommending a quick look at the example living style guide and sample scenario showing cafes in New York to get an idea of the outcome before coming back for the entire tutorial.
Design should be an iterative process where ideas are explored, evaluated, and refined.
For each of these different phases we have a bunch of tools that we use. A typical design team might use tools like paper sketching to explore, a diagramming tool like Omnigraffle to capture a flow, a graphics tool like Sketch or Photoshop for high-fidelity mocks, and perhaps a tool like Framer or Marvel to explore illustrations, or get feedback on a user flow.
But unless it’s for the purpose of an animation, it’s rare for a designer to write code in their day-jobs. And despite the popularity of the agile manifesto, collaboration between designer and developer is often reduced to consultation.
In my experience, when a designer presents work to a stakeholder its typically in the form of high-fidelity illustration. There’s an expectation that precision equates to perfection, and presenting something like a rough paper sketch would, in most cases, be considered careless.
Despite the fidelity of a screen compositions, these outputs are not the final stage in refining an idea, but actually just a latter step in the process of exploration and should be treated with similar regard as a paper sketch.
No matter how experienced you, your team, or your stakeholders are, I don’t believe that it’s possible to look at illustrations of an interface, suspend disbelief, imagine someone using the interface, and give useful feedback.
Collecting feedback on a concept by looking at it one screen at a time separates the product from the natural cadence that it would be used. Screens intended to be shown for a passing moment might be flagged as too boring, or taken out of context of an overall flow.
Feedback on illustrations make it extremely difficult to understand rich experiences, especially when the interface is intended to be used on a hand-held device.
Feedback on illustrations prompt refinement on aesthetic issues rather than potentially more impactful issues of usability.
The most significant issue with using illustrations for collecting feedback is that it creates a separation between content and design, with content generally becoming a second-hand citizen in the process.
Good designers will take into account edge-cases for content (for example unusually long names, or when content is omitted) but in most cases designs are evaluated with a snapshot of content.
In the world of research there’s a truism that the worst number of people to test with is one. In the same spirit, it’s incredibly dangerous to design a solution around a snapshot of content, especially if it’s made up.
Tools like Sketch are still essential for the design process. They’re the fastest way to take a general layout and quickly explore broad variations1.
Designing in the browser does’t mean abandoning your current design tools, and not making high-fidelity comps. It means a perspective shift from final deliverable to another useful tool.
That was the stick. Now for the carrot.
Designing in the browser means finding a design process that involves your concepts being evaluated in the browser.
Understanding (and using) the medium that you’re designing for will make a lot more sense when you actually try it for yourself.
If you’re still skeptical, consider creative geniuses of artists like Michelangelo and Picasso. Their workflow involved countless sketches of varying fidelity exploring composition and detail before starting a painting, but even with all that preparation, once painting had started it was still common to paint over large areas and make dramatic changes on the final canvas.
Some direct, and incidental benefits of designing in the browser include:
That’s a pretty impressive list of outcomes, and I can’t guarantee that designing in the browser will help everyone the same way.
Also, designing in the browser isn’t the only option that will lead to those benefits, depending on your team, your workflow, your product, and your company, you might already have alternative practices2 in place that are leading to these same outcomes. YMMV.
There are dedicated prototyping tools like Axure that act as a proxy for writing code in favor of a GUI which then generates HTML on your behalf.
These tools terrify me because on the surface the drag-and-drop nature of the interface make them appear simple3, but that initial simplicity often hides an immense amount of complexity that people dedicate months (or years) mastering a specific tool when they could have been investing that time learning more general purpose programming tools.
Another approach could just be hand-crafting HTML. This approach is okay-ish for the simplest of projects like a static marketing website, but for most situations suffers many of the same obstacles of high-fidelity comps in that it’s very difficult to explore different sets of data.
The final option is to borrow a tool from our developer friends and use a MVC framework.
A framework gives us some structure to work around, and while every framework has an initial learning curve, in the long term will make our lives a lot easier.
The biggest problem that we face is deciding which language to use, and which framework to pick, todomvc.com is a site that assembles sample apps from web MV* frameworks and currently lists over 50 options.
When choosing a framework to use I look for the following:
Because our aim is to create experiences that are prototypes or proof-of-concepts, rather than release production ready code, then the following are mostly irrelevant:
The final consideration should be to consider the framework your development team is already using (or planning to use).
If you make a short-list of frameworks you’re interested in using, and one of those happens to be what is already being used in your company, then it’s a pretty strong argument to use that common framework, not because there is potential to re-use code, but because you’ll have access to a team that can help you learn that framework.
But if the framework your development team uses doesn’t meet your shortlist for a low learning curve, documentation, examples and community then it might be better to use a separate framework that better suits the criteria for your design team rather than to use a common framework.
The rest of this post continues by showing examples using Vue and Fieldbook. You can follow along to get a general idea, but you’ll need to adapt a lot if you choose to use a different framework.
This next section walks though the steps of taking an early concept and, the steps needed to get it transferred into the browser, and running off live data.
I’ve broken this process down into smaller steps so you can get a better idea of what’s happening, and learn more about Vue, in practice many of these steps would be skipped over.
This section assumes that you’ve already installed Vue.
Let’s use the example of making a web app that helps people find independently operated cafes in a city.
Imagine that you’ve explored a range of directions, and settled on a layout that shows cafes as a grid of cards, where each card shows some details about the cafe. We’ve also decided that we’ll have two ways to sort the cards. By default in alphabetical order by name, and another based on how close they are to your current location.
A good first step is to start by creating a sensible semantic markup in HTML. By not worrying about what the page looks like, but instead how it’s structured is a good way to avoid adding markup that isn’t needed.
For now I’m adding the ‘map’ only as a placeholder. It won’t actually show anything, but I’ll add it as an element so at least we can plan around the space that it will use.
Obviously, with no styles applied, this doesn’t look so great.
Copy and paste the code for the cafe card a few times so that we have a few elements on the page to work with as we apply styles.
With some basic CSS in place, our page is starting to look a little more respectable.
And because we’re in the browser, we can immediately start to get a feel for how the screens will adapt to different viewports.
I might get some criticism for starting from the approach of a desktop, but personally I think the choice of mobile/desktop-first is irrelevant as long as you’re taking a responsive-first approach.
So the annoying thing with our page right now is that we only have 3 cafe cards. We can copy-and-paste more into the HTML, but that also becomes annoying when you want to make a change across all of the elements.
For example, I’ve just realized that as well as the location, I also want to show the hours that the cafe is open.
What would be great would be if we could take this code:
And get the same result just by using a single
If we could do that, then our HTML would suddenly become a lot more easier to read:
Guess what? That’s exactly what Vue allows!
We can do this by creating a new file
Notice that our HTML is wrapped in a
<template> tag, and we’ve also copied over the relevant CSS for the cafe card and wrapped that CSS with a
You might have noticed the
scoped attribute in the
<style> tag. This is optional, and means that any CSS that we set here will only apply to the HTML in our template. So although we have a CSS rule for H1, because this CSS is scoped these styles won’t be applied to any H1 tags in other parts of the page.
What I love about this approach is that everything that you need for this component - the HTML structure, and the CSS is all in a single file, meaning you don’t have to jump around to figure out where a specific style is. As projects become more complex, this approach helps keep them manageable.
A couple steps before this actually works, we need to tell Vue about this new component we’ve created. This is done in a file called
And also add a script tag in
index.html so that it everything can connect up.
That’s great, but each card still has the same repeated details.
Let’s make a change by passing in a name for each cafe.
Now back in
CafeCard.vue we’ll need to make some changes, first to let Vue know that we’re passing in a property called name to the component, and also in our template so that it actually uses that name.
We’ll do this by adding a
<script> tag to our
.vue file, which for now just defines props as an array that contains all the properties we want to pass into the component. For now we’re just passing in name so the array only has one item.
Now our screen is starting to have some dynamic data, with the titles of each cafe being used in the card:
Now we have 5 cafe cards, but we don’t want this to be hard-coded into our page. We want a solution that works with minimal fuss if we have 1 cafe, or 100 (or none).
Vue includes a directive for looping over an array of items that allows us to go from this:
This is assuming that
cafeNames is an array that contains the names of all the cafes e.g.
["Daily Press", "Cafe Grumpy", "Stumptown", "Third Rail", "Gimmie! Coffee"].
Where do we create this array so that Vue can use it? We can pass it into Vue in our
main.js file like so:
Now that we’re set up to pass information into our cafe-card component from a data source (currently just a simple array) lets’s use this to pass in all the details for each cafe.
Instead of an array of Strings, let’s create an array of these objects:
index.html we’re no longer passing in a name, but actually data about the entire cafe, so lets make some changes to reflect that:
Finally, in our
CafeCard.vue let’s make use of this new data:
Now our template code doesn’t include anything hand coded, and everything is being rendered from our data source.
An interesting thing about this approach of making our own components, is that they can be nested within each other just like any other regular HTML tag.
Just like we made a component by creating a
CafeCard.vue file, I’m going to follow a similar process and create a
GoogleMap.vue which contains all the logic to render a map showing a specific location, and then use this new component in the cafe-card component.
Here’s our page with a map shown on each cafe card.
Right now we have two components, one for the map, and another for the cafe card.
A component can represent anything from as small as a button, to something of slightly more complexity like a card that bundles some related information, or a component could represent an entire screen!
By thing as components as modular elements of the screen, we can start to combine them to create more complex layouts, but also as a way to organize our project into sensible bits that make it easier to manage over the long term.
Let’s take all the code that’s currently used to manage this grid of cafes and put it into a component.
We won’t get any immediate payoff for this, but it will be more obvious why this is useful in the following steps.
We’ve moved all that data source stuff into our grid component so
main.js gets a little more readable
index.html file is now crazy lightweight.
It’s interesting to reflect that functionally nothing has changed, but by adding a new component we’ve for the grid view we’ve moved a bunch of complexity into it, but that sort of makes sense since now pretty much everything important about that grid is in a single place rather than being split between
Something great about rendering components from a data source is that you have the ability to manipulate that data source - you can add, remove, or alter items in your source, or you can change the order that items are presented which will all affect how our page lays out.
Vue includes options for sorting, limiting, and filtering arrays. Here’s a quick change that simply orders our cafes alphabetically.
What would be really cool tho, would be to allow us to change the order that cafes are presented by clicking on our options in the navigation section of the page. So let’s do that!
CafeGridView.vue we’ll add to our sort option links code that calls a method
setSortOrder. We also need to create this method by adding it to our
<script> section. This is a really simple method that just sets our sort order property to whatever get’s passed in as a parameter in the method.
When we loop over our cafes, instead of sorting by a value that’s hard-coded, it sorts based on whatever value sortOrder currently is.
We also need to make an update to our data source to add in some options for how far away that cafe is.
We’ll just fake it for now and enter in some pretend values, but obviously in a functional app these distance values would be calculated based on your actual current location.
Something that’s really useful is being able to explore changes to our data source without having to go in and edit our code.
For this example I’m going to show how to connect the data to fieldbook.com, which is similar to a Google Spreadsheet, except that it has convenient ways for us to grab that data in a format that’s easy for us to use in Vue.
To start, we’re going to change the
<script> section of
CafeGridView.vue to the following:
data block is suddenly a lot simpler because we just set cafes to the value of an empty array.
We’ve added a
ready block, which like the name suggests is code that is executed when the component is ready to be displayed.
This ready block includes some code that requests our cafe data from fieldbook.com, and then when it’s done, it updates our
cafes array with that data.
We also need to make some updates to main.js
A lot of variables here are based on the fieldbook that I have made at fieldbook.com/books/56c3c166589a1f0300c53acd feel free to use this yourself, but if you create your own fieldbook book you’ll need to update the variables to match your details.
Now with our dependencies up to date, and our data being sourced from fieldbook.com it’s easy to make updates to the data without updating the project code.
At the moment our app only has a single page, the grid of cafes. Sometimes a project may only require a single page, but even on these projects I like to include a live style guide that acts as a place to store documentation for custom components that have been created.
So this next step will show how to add code that manages what to display based on the current URL.
We’ll set it up so that navigating to
/#!/cafes/new-york shows our current grid view of cafes, and navigating to
/#!/styleguide shows documentation about our project styles and custom components.
First we’ll create a new component
StyleguideView.vue that will act as documentation for our components.
Next we need to add code that manages which component to show based on what the URL is. This is common task in web apps, and code that does this is called a router.
Router functionality isn’t a core component to Vue, but like vue-resource we can list it as a dependency for our project, and have it installed as an add on.
The most significant changes happen in our
main.js file, here’s an extract of the most interesting changes:
index.html also gets changed where we use the special
<router-view> component that comes as part of using vue-router.
A benefit of having a live style guide in HTML, rather than a static style guide as a PDF, and components that are data-driven is that we can make the style guide dynamic and use it to explore how our components adapt to ad-hoc sets of data.
Basically, the approach I use is to add a
<textarea> for each component that allows you to update the data that’s being used to render that component.
This creates something called two-way binding between our cafe data object, and the textarea so that any changes made in the textarea update the component in real time making it easy to explore how our component adapts to variations of data that’s used.
So far our prototype has only been available when run locally from our computer. For an internal team sometimes that’s all that you need, but when you want to get feedback from people outside of your team you’ll want to have your prototype deployed to the internet.
Again cli-vue helps us prepare for deployment. Like we use the command
npm run dev to run a local server for development, we instead use the command
npm run build which takes all our code,bundles it together, and minifies it so that it’s the fastest download possible.
Then all you need to do is upload
dist/build.js and any css or image files needed (for us this includes
default.css) to a web host.
I’ve uploaded these files for the cafe-finder prototype to getforge.com which will host your first site for free, and deployment is as simple as dragging a zip of your files into their web interface.
You can browse the project live at cafe-finder.getforge.io/#!/styleguide.
This section includes steps for installing the tools you need to get going with Vue, and how to use the github repository to follow along with the tutorial activities.
Setting up your computer for development in a new language can take a bunch of steps. Don’t worry, this is something you’ll only need to do once.
Here’s a list of the things we need to do:
Let’s get started!
Xcode is for more than just iOS apps, it’s a general-purpose IDE and set of development tools for a range of languages.
We won’t be using Xcode directly, but we need some of the tools that come with Xcode as a dependency for other tools that we’ll be using.
node -vwhich will print out a version number if they were installed, or the message
command not foundif they were not.
You can start using Vue simply by adding a script tag to your html files, but installing the vue-cli package includes some nice tools that help organize our code, and speed up prototyping.
vue-cli is a node package, so we install it from the command line using npm.
npm install -g vue-cli. This is asking npm to install the package ‘vue-cli’ and make it available globally.
sudo npm install -g vue-cliwhich is the same command, but giving npm access to superuser permissions. You’ll be promoted to enter your OS X password.
Git is a command-line tool for version control that allows a team to collaborate on text files, track changes, and rollback to earlier versions if needed.
We’ll use github to store our repository online, and use their desktop app instead of interacting with git through the command line because it’s a lot easier.
Atom is a text editor created for writing code. If you have a favorite editor you can use that instead, but Atom does have some convenient shortcuts with the Github desktop app.
.vuefiles (Open Atom → Preferences → Install → search for ‘vue’ and install ‘language-vue’ which should appear as one of the top search results).
That’s it! Your computer is now set up with all the tools you need to make using Vue easy.
I’ve created a github repository for this tutorial where every activity is available as a commit in the project. You can use this repository to jump around different phases of the project, run the project at these different stages, and explore the code at each stage.
When we clone a repository, it just means downloading a copy of the project onto your computer.
A repository is more than a directory of files, it includes snapshots of the project at different stages of the project, and the changes that were made (additions, deletions, and modifications) to files at each step.
In this sense it’s like a really smart undo, or time machine, allowing us to jump around to see the project at different times (and if we want to revert back to an earlier step).
The Github desktop app should open to show a history of commits within the project. You can click on each commit, expand it to see what files were changed as part of that commit, and see in more detail what changed in that file at that step (text highlighted red shows lines that were deleted, and highlighted green to show additions).
One of the nice things about using Atom as your code editor is the close integration with the Github desktop client.
Now let’s actually open up this project in Atom and start making some changes…
When cloning a repository, by default we’re taken to the most recent commit that was made. Because we want to start the tutorial at the first step, and then work through the linear series of steps we need to jump back to the very first commit in the repository.
The Github desktop app doesn’t have this feature, so we’ll have to jump into the Terminal to do this through the command line.
git checkoutand then paste in SHA, and then hit return key.
npm installand hit return key.
This command starts of a process where npm downloads and installs any packages that we depend on for vue-cli to work (also known as dependencies).
These dependencies are listed in a file called packages.json in our project folder, and as you run this command you’ll see a folder called node_modules be created and a folder added for every package that is downloaded (the terminology is confusing, but for now think of package, dependency, and module as different words for the same thing).
Finally, we’ll actually run this project, so we can see this project in the browser.
npm run devand hit return key.
open http://localhost:8080to launch your default browser.
You can now follow along the activities in the tutorial from this step, and if you get stuck at any step you can always use the
git checkout command to jump to a specific step of the tutorial.
A lot of effort has gone into creating tools that automate the creation of HTML and CSS from the layers of a high-fidelity illustration. What I wish existed was the reverse: A tool that took an existing HTML concept and imported it into layered comp that could then be manipulated. ↩
A good example could be that your company has a rapid development cycles, healthy collaboration between designers and developers, and a culture that promotes experimentation and testing. ↩
The latest of these tools is Adobe’s Project Comet. I encourage you to go view the demo, and get excited by what you see because the outcome is exactly what we’re trying to achieve, but carefully consider investing in learning a specific tool when the same result can be achieved with existing development tools. ↩
There aren’t any decent free tools that support collecting user feedback, so for this you’ll need to pay a small monthly subscription for access to these tools. ↩