Turning website design files into a combination of HTML, CSS and JavaScript is the bread and butter of many front-end web development jobs, but there’s a part of this work that doesn’t neatly fit in to tutorials on any specific topic. There’s a process of breaking down a design and figuring out how to approach the build that seems to fall under on-the-job training for new front-end developers. It’s not something taught alongside core technologies (no matter where we are learning those technologies—college, bootcamp, or on our own).
In this post, we’ll take a look at how to go from design to code, and why you might want to follow a process like this instead of just diving into code head-first—which, let’s face it, we love to do! The contents of this post are based on my experiences onboarding new developers, the kinds of conversations we’ve had, and the help and feedback I’ve provided in those situations.
One reason the process of moving from design to code is a core professional skill for a front-end developer is that without having some way to dig in and predict how you will approach something, it’s very difficult to provide an estimate for how long it takes to make or what questions you might need answered before you start. Many designs might appear simple at first glance, but quickly become complex once you get into the weeds. I’ve seen this lead to overpromises, which often leads to tighter deadlines, stress and even worse side effects. Suddenly everything takes much longer than we initially thought. Yuck. Let’s see if we can avoid that.
Evaluating a design
As a way to talk about this, let’s use an example design for a “marketing-style” web page and assume we have been asked to implement it. We can also assume this site is created in a context where marketing professionals may come in and edit the content via some content management system (CMS), re-order the sections, replace images, and make style changes. So we need to decide on the components of the page that will be the building blocks used in the CMS.
This gets at another reason that this can be missed in education: often in our own solo projects, we can have static content right there in the HTML, and component parts aren’t going to be Frankenstein-ed together by strangers to form whole new pages and sections. But once you step into more real-world dev situations, things are a lot more dynamic, and we are often working at the layer of “make things that a non-developer can use to make a web page.”
Let’s use this website for a clinical trial is example. As we can see there are a lot of familiar design elements. Marketing sites tend to share common patterns:
- a big hero section
- product images
- small separate sections of short-form content emphasizing one thing or another
- information about the company
- etc.
On mobile, we can take it as a given that in each section, the left columns will stack on top of the right, and some other fairly typical reflow will happen. Nothing structural will change on mobile. So what we are looking at is the core of the design.
In this example, there is a header, then a lot of distinct sections, and a footer. At a glance, some of the sections look kind of similar—several have a two-column layout, for example. There are button and heading styles that seem to be consistent throughout. As soon as you take a look at something like this, your eye will start to notice repeated patterns like that.
This is where we start making notes. Before we do any coding, let’s understand the ideas contained in the design. These ideas can fall into a few buckets, and we want our final product—the web page itself—to correctly represent all these ideas. Here are the buckets I commonly use:
- Layout-level patterns—repeating layout ideas and the overall grid
- Element-level patterns—headings, text sizes, fonts, spacing, icons, button sizes
- Color palette
- Structural ideas—the logical organization of sections, independent from the layout
- Everything else—ideas that are only present in one component
Documenting the patterns this way comes in handy for figuring out our CSS approach, but also for choosing what HTML elements to use and starting conversations with the designer or other stakeholders if something is unclear. If you have access to the source files for the design, sections and layers might be labelled in there that give you a good idea what the designer was thinking. This can be helpful when you want to talk about specific sections.
So let’s look at the ideas contained in our example design. We’re going to do several passes through the design, and in all of them, we’re going outside-in, top-to-bottom, and left-to-right to ensure we evaluate every element. In each of the five passes, we’re looking for stuff that goes into just one of the buckets.
We’re unconcerned with getting this list perfect; it can always be changed later—we just want to record our first impressions.
Pass 1: Layout-level ideas
In this design we have a few layout ideas that stand out right off the bat.
- A header with a horizontal nav section
- A main content column within the content area—left and right edges align within all sections from header to footer
- Sections with two columns
- Sections with a single centered column
- Sections with a single left-aligned column
- A footer with three columns
- Fairly generous padding inside each section
First impressions
We should note any other first impressions we have during this first pass, good or bad. We can never have a first impression twice, and some of our gut reactions and questions can be forgotten if we neglect noting them now. Plus, identifying specific stuff that you like in the design can be nice when we get to talking with the designer. It both helps to celebrate the good stuff and mix it in with other constructive criticism.
Our first impressions might be things like:
- 👍 The design is clean-looking and readable.
- 👍 The sections are all titled by questions (good, helps draw reader in and gives each section a clear purpose).
- 🤨 Question marks are used inconsistently in the titles (possibly just an oversight?).
- 🙋♀️ Sometimes there are very similar font sizes right next to each other (may need to follow up to see if this is intentional because it seems a less slick and professional than the rest of the site).
- 👍 The logo is nice with that little gradient going on.
Pass 2: Element-level ideas
Here are things we might notice in this second pass:
- Primary (blue) and Secondary (white) button styles, plus a “Learn more” button in the header with a little arrow (an expanding menu maybe?)
- Heading and sub-heading styles
- Three “body text” sizes (
16px
,18px
,20px
) - A “dark-mode” section where text color is white and the background is dark
- A consistent presentation of “image & caption” sets
- Custom bullet points of various kinds
- Inline links in the text are underlined and, other links, like those in the footer, are not.
- A repeated card component with an icon on top, and a heading and a list inside the card
- The logo repeats a few times in different contexts/sizes.
- The footer contains uppercase headings that don’t appear elsewhere.
Pass 3: Color palette
There is not too much going on in this design color-wise.
- blue/purple primary color
- light/dark body text colors
- light/dark link colors
- nice gradient under the word “hope” in the logo
- light gray background color
- dark navy background color
- specific red and green “checkmark” and “stop” icon colors
Some design tools let you export the color hex values used in the design file, or even full-on Sass or CSS variable declarations. If you have that option, use it. Otherwise, find your own way to grab those values and name them because those are the foundation for lots of our initial CSS work.
Throughout our CSS and other code, we want to be refer to colors with labels or classes like “primary” and “secondary” that we can reuse throughout the code. This makes it easier to adjust values in the future, and to add themes down the line if we ever need to.
Pass 4: Structural ideas
This is where we might actually name the regions of the page in ways that make sense to us, and identify the hierarchy of the content. We can start to understand the accessibility needs of our implementation by documenting in plain language what we see as the nature and structure of the content in the page. As always, going outside-in, top-to bottom, left-to-right as we make our evaluations.
Focusing on structure helps us figure out the underlying patterns that eventually become our components, and also helps us understand the way we want people who use assistive technology to perceive the content. In turn, that guides us as far as what HTML elements we need to use to write semantic HTML. Semantic HTML speaks to the nature and structure of the content so that it can be perceived correctly by browsers. Browsers use our HTML to create the accessibility tree that assistive tech, like screen readers, uses to present the page. They need a strong outline for that to succeed and semantic HTML provides that solid structure.
This means we need to understand the nature of what’s on the page well enough that we could explain it verbally with no visual support if we had to. From that understanding, we can work backwards to figure out the correct HTML that expresses this understanding via the accessibility tree, which can be inspected in you browser’s developer tools.
Here’s a quick example of the accessibility tree in Chrome if everything on the page is a div
, and if elements are correctly chosen to match the nature of the content. Determining the best element choice in a given situation is outside the scope of this post, but suffice it to say that the expressive, non-”generic generic generic” accessibility tree below is entirely created with HTML elements and attributes, and makes the content and its organization much easier for somebody to perceive using assistive technology.
So, in this fourth pass, here are notes we might make:
- Top-level structure:
- Header
- Main Content
- Footer
Not so bad for the first top-to-bottom pass. Let’s go a level deeper. We’re still unconcerned with the child inside elements of the sections themselves yet—we want just enough info to label the top level items inside each sections.
- Within Header there is:
- Home link
- Navigation section
- Within Main Content there is:
- Hero section
- Short explainer about the disease itself
- Explainer about the treatment
- Intro to the trial
- Explainer with more details about the trial
- Statement about who can join the study
- Call-to-action to participate
- Short explainer about the company
- Within Footer there is:
- Logo
- Summary Sentence
- Some lists of links with titles
- Divider
- Copyright notice
This pass reveals a few things. First, the Header and Footer sections are pretty shallow and are already revealing raw elements like links and text. Second, the Main section has eight distinct subsections, each with its own topic.
We’re going to do one more pass here and get at some of the deeper details in those sections.
- Header home link—Woohoo, it’s just a link and we’re done.
- Header nav—This is an expanding hover nav that needs JavaScript to work correctly. There are probably lots of accessible examples to follow, but still will take more time to develop and test than if we were working with raw links.
- Hero
- Title
- Column 1
- Subtitle (we missed this in the first element-level pass)
- Paragraph
- Primary button link
- Secondary button link
- Column 2
- Hero image
- Disease Explainer
- Title
- Paragraph
- Unordered list
- Large text
- Unordered list
- Image and caption (figure and figcaption)
- List of links
- Treatment Explainer
- Title
- Column 1
- Paragraphs
- Column 2
- Image and caption (figure and figcaption)
- Trial—Intro
- Title
- Column 1
- YouTube Video Player
- Column 2
- Paragraphs
- Trial—More Details
- Title
- Subtitle
- Cards (with Icon, Title, and List)
- “Who Can Join” statement
- Title
- Column 1
- Paragraph
- Unordered list
- Column 2
- Paragraph
- Unordered list
- Call-to-Action
- Title
- Paragraph
- Secondary button link
- About the Company
- Title
- Paragraph
Yowza, that got long fast! But now we understand pretty well the kinds of things we need to build, and what parts might be tricky. We also see that there may be some helper components to be built that aren’t quite represented by any one of these sections, for example, a two-column layout component that stacks to one column on mobile and has a title on top, or a generic “section container” component that takes a background and foreground color and provides the right styles plus standardized internal padding.
Incidentally, with this breakdown we’ve done a pretty good job expressing the final accessibility tree we want our HTML to create, so we are well on our way to having the implementation be a smooth experience without a lot of re-work to get accessibility right.
Pass 5: Everything else
What are some other ideas contained in this design, things that stick out, or challenges we notice? Maybe not much, but this is kind of the other side of the “first impressions” notes. Now our heads are filled with context for what it is in the design.
If something stands out now, especially if it’s a question about how something works, capture it. An example is, “Hmm, what is the ‘Learn More’ link in the nav supposed to do?” The answer might be: “It’s a list of links to each section that open when you hover there.” Every now and then, a designer expects that this kind of thing is already implied in the design, even if it is not explicitly documented, and it only comes up at the design review stage after that thing is developed—which is often too late to correct without affecting dates and deadlines.
We should also now look deeply and identify any hidden “glue work”— things like getting our styles in order, handling mobile, configuring the CMS, adding and testing authoring options and arrangements for our building blocks, and adding automated tests. Stuff like that.
At this point, we are ready to nail down exactly what components can be created in the CMS. Maybe we already have some of the basic setup done in the current system from past work. Whatever the case, we have enough to draw on to offer a decent estimate of the work needed, grouped into categories. For example, we might categorize components that:
- are already 100% ready (no dev time needed),
- exist but need tweaks for this new purpose (predictable dev time needed),
- are totally new, but the path is obvious and safe (predictable dev time needed),
- are totally new and need some research to implement. Or the design is unclear, or something about it gives you the heebie-jeebies and you need to have discussions with stakeholders. The earlier you can spot this, the better. Talk it over with whoever is running the project.
Now we have enough information to make a reasonable estimate. And more to the point, we’ve reduced the total time the project will take, and limited the trouble we might have along the way, because we’ve gained several advantages from planning it out.
The advantages of having a process
The exact steps we take and what order they are completed in is not the main point. What matters most is understanding the kind of information you need to gather when starting on a project. You might have your own ideas about how the work is done and in what order, whatever works for you is great.
Here are the advantages I’ve realized when assessing a design with a process in mind, compared to just kinda diving in, “getting stuff working,” and handling things as they come up.
You do a little extra discovery
As much as we’d like every project to arrive fully formed and perfectly ready to start, in reality, designs often contain assumptions that might be impractical to implement, or contradict something else we care about, like accessibility. In that case, you can assess the whole thing up front and get the conversations started with people who can resolve those issues early in the process. This can happen while you dive into the pieces that are ready to code, and will stop you from bumping into these roadblocks later when you are about to build that part of it. Flagging concerns early is definitely appreciated by the people who need to solve them.
You can be helped by others
Without a plan, it can be difficult to understand how far along you are in completing the project, as well as knowing if you need help meeting a deadline. Even if you do need help and are able to ask for it, it’s tough to use extra helping hands effectively without the work being broken out in to separate little chunks that be easily divided. When you have a plan that makes sense, you can quickly delegate certain tickets, knowing that the jigsaw pieces will fit together in the end.
It’s easy (and common) for a new developer to think think that huge workloads and working around the clock is a good thing. But as you mature in the role, you’ll see that having a deep understanding of the whole picture of a project, or even a single ticket, is more valuable, while creating a better impression that you are “on top of things.” Recognizing early that a timeline doesn’t look right gives you options about how to address it in ways other than trying to be a hero and throwing some weekends at it.
Component architecture flows better
Architectural decisions are the worst for me. Naming components, figuring out where stuff should live, which components need to talk to each other, where to break stuff up into smaller components. A lot of those choices only make sense when we look at the bigger picture and think about all various ways that certain elements might be used by visitors and content creators. And a lot of these choices are marginal—choosing the “best” option between two acceptable solutions can be a huge time suck or completely subjective.
Have a process helps with that because you are going to get all, or most, of the information you need about the designs before digging deeply into the development work. For me, figuring out what pieces I need to make, and figuring out the best possible code to make those pieces, are two different things. Sometimes what I need is not the thing that comes most naturally from the code. And sometimes, after learning a bit about what is needed, I can avoid time spent bikeshedding marginal decisions because it’s more clear which decisions truly don’t matter.
You still learn new things as you write the code, of course, but you’re now better prepared to handle those things when they pop up. You even have a good idea about the kinds of that might present themselves.
Styles make more sense
As you plan the work, you can truly figure out which styles are global, which are section-specific, which are or component-specific, and which are one-off exceptions. If you don’t already have a system you like for this, Andy Bell’s Cube CSS pairs very well with the kind of breakdown I’m talking about. Here’s a video of Andy working through an example with Chris Coyier that you can check out for more about this approach.
Accessibility starts early in the process
This one is huge for me. By really understanding the ideas contained in the design, you will have an easier time picking semantic HTML elements and finding appropriate accessible patterns to build out what you see there. Accessibility can work its way into the daily work you do, rather than an afterthought or extra burden. Our perspective becomes that high-quality front-end code correctly expresses the nature and structure of its content to all users, and accessibility is how we measure that.
After a pretty short period, you’ll see how often designs conform to one known pattern or another, and the flow of breaking something down into known patterns to implement will speed up dramatically. Carie Fisher nicely sums up ideas related to this “Accessibility-first” approach.
Wrapping up
Like I said at the start, a lot of this falls under on-the-job training, the “oral tradition” of web development. It’s the kind of stuff you might hear from a senior developer on your team as you’re getting started in your first front-end role. I’m sure lots of people would have different priorities than I do and recommend a slightly different process. I also know for sure that a lot of folks out there work in situations without a solid process in place, and no one senior to consult.
If you are in that situation, or not yet in your first role, I hope this gives you a baseline you can relate to when you think about how to do the job. Ideally the job is not just diving in and putting stuff in divs until things look “right” but that is often our mode of operation. We are eager to make progress and see results.
I’m very grateful that I did have somebody working with me at my first development job who showed me how to split up pieces of a design and estimate work for large, long-term projects. That’s what inspired me to start thinking about this and—as I began supervising other developers and teams—thinking about how I wanted to adapt the process and make it my own. I also realized it wasn’t something I’d noticed people talking much about when teaching technical skills about using a particular language. So thanks, Nate!
Thanks also to Drew Clements and Nerando Johnson for providing early feedback on this post. You are the best.
The post A Step-By-Step Process for Turning Designs Into Code appeared first on CSS-Tricks. You can support CSS-Tricks by being an MVP Supporter.