Reflections of a User Interface Developer
“A craft is a pastime or a profession that requires particular skills and knowledge of skilled work.”
I think building a User Interface (UI) is most definitely a craft and it’s a craft I’ve been perfecting for many years.
I’ve worked at a tiny agency (my first job), at a medium sized agency, at two large organisations, spent some time freelancing in another country, and now I am working at an email marketing company: Campaign Monitor.
This has given me exposure to working in different types of teams both in terms of size and experience. It has allowed me to work on projects of varying scale and timeframes — from simple static brochure sites to complex rich applications used by millions. Working the Waterfall way, working the Agile way — or variations of it, being the mentee and the mentor, leading teams, being involved in recruiting new developers, and of course building a ton of UI.
I thought I’d take some time to reflect on the lessons I’ve learned and the things I’ve come to value. These reflections are the result of my personal experiences throughout my career. Hopefully a few of these give you something to consider or even resonate with you.
“Attention to detail, empathy, curiosity, and passion is key to being a great UI developer.”
There are a lot of small details you need to be on top of when putting together a UI—especially a large responsive one—therefore it’s easy to start letting things slip and to begin losing that care factor.
Having both a strong attention to detail and empathy for the user is crucial, unfortunately this can rarely be taught — you either have it or you don’t, whereas the more technical aspects of the craft can be learned.
For the UI developer who scrutinises over every decision he or she makes, who doesn’t make hasty decisions, who takes the time to get it right upfront, who conducts solid stress/browser/device testing, who thinks of the edge cases, and who communicates heavily with his or her team asking all the relevant questions, will continue to deliver top notch UI’s that are performant, accessible, robust, and future proofed.
I have found taking a little extra time upfront and applying these traits to my work is that I rarely get anything coming back needing to be reworked or fixed—that extra effort and care pays dividends both to the user and to the business—once it’s out in the wild.
If you build things blindly and in a silo then chances are you’re going to have to do a lot of rework along the way, and you increase the probability of delivering a subpar experience for the consumers of the UI you’re building. There is a tax to pay when you don’t take the time to throughly understand what you’re building, and that’s not just understanding the intricacies of the UI but things like “what are the main benefits this feature brings to the customer?”, “are we planning on using this feature elsewhere?”, “how do we measure if this feature will be successful?”, etc. You should be really invested in what it is you’re working on.
Being curious and bringing that curiosity to everything you do helps make you a better developer. Question everything you’re unsure about with fellow developers, designers, UX’ers, and product managers.
As for passion, well us UI developers are a passionate bunch, if I don’t see that in the other UI developers on my team then I begin to wonder.
“Soft skills are more important than technical skills, and respect for your peers is paramount.”
I deeply believe this and having been recruiting UI developers for many years has really made me see how important this is.
In fact, I tend to prefer hiring more junior/mid–level UI developers with the intention to train them up in the technical aspects of the craft and I’ve had good experiences with this in the past. I’ve found their willingness and enthusiasm to learn and their attitude in general has always paid off, and made mentoring them something I’ve enjoyed.
What can happen—and this definitely isn’t always the case mind you—with a very top heavy team of senior developers is that everyone can think they’re an expert and be unwilling to learn from each other, this can stunt team collaboration and personal development.
Nobody knows it all—being comfortable with seeking help and admitting you still have things to learn goes a long way.
At the end of the day you have to spend a considerable amount of time with your peers—more than anyone else in your life, so those relationships need to work. Working in teams where respect and humbleness is a strongly held value will enable you to do your best work and leave room for you to focus on and really care about what it is you’re building.
I’m still not as good as I’d like to be at any of this, in fact it’s always been a struggle for me. I’ve found learning to be patient with myself as I work through this and finding a manager (or mentor) who really listens has helped me a lot.
I also highly recommend having a read of this: Be Kind.
“Working in an Agile manner, doing continuous deployment, and working in a cross-functional team is the best way to work.”
I don’t think I need to sell the benefits of working in an Agile manner and it seems most people nowadays are working that way—in some flavour or another—I know for me it’s a prerequisite when considering any position.
I love it when continuous deployment can happen and it’s more than just getting code to production faster. It’s a great way to work as it really instills a sense of personal responsibility, responsibility for things like the quality, stability and effectiveness of the product. And along with that responsibility is the pride and reward in knowing that your code is released and in front of users—hopefully making their lives easier.
Writing the code to build a UI is only part of the job. A large part of being a UI developer — definitely a senior one — is liaising with design/UX, product management, and back-end developers. You are the bridge between design/UX and back-end development. Working very closely with these people is absolutely crucial.
If you’re working in a cross-functional team set up then you should have easy access to all the information you need to make the right decisions about the thing you’re building, and if you don’t then getting that information should be easy.
One of the worst things that can happen when tasked with building a UI is being handed the blueprints to the build — a PSD file, a Sketch file, whatever it is — in a highly polished state already signed off by stakeholders.
I believe working in a true Agile fashion within a highly collaborative cross-functional team allows you to craft the best possible UI and out of all the people in your team the UX designer is the person you need to be working most closely with—this is an important relationship—one I like to think of as a Maverick and Goose type relationship.
Working in an environment that embraces collaboration, where all team members have a say in the team’s goals and roadmap, makes for a happier high-performing team.
“Anyone can write CSS but writing CSS well is hard.”
Yes CSS is very easy to write, however, its simplicity is deceptive and once you start writing it at any scale and within a team, then CSS quickly becomes difficult. And if you aren’t experienced at building large scale UI’s then your CSS will spiral into an unmaintainable mess.
You need to know how to architect your CSS, how to sensibly break up the UI into well constructed reusable components, how to abstract really common UI patterns and layouts into highly reusable utilities and modules, how to carefully define base styles that seep into the entire UI, but only to a point, how to develop UI’s that work across a variety of screen sizes and with an assortment of input mechanisms, how to make all this work in a highly maintainable way, the list goes on. All the while dealing with CSS’s cascade, specificity, and fighting everything being in a global scope.
When working with CSS at scale many of the same principles from software engineering apply, principles like:
- Don’t Repeat Yourself.
- Single Source of Truth.
- The Single Responsibility Principle.
- The Separation of Concerns.
- The Open/Closed Principle.
After building UI’s for a while you come to realise that you need a library and a well-defined architecture for each of your project’s CSS as starting from scratch each time is a little crazy. For me I built this up over years, and a few years ago I had an opportunity in a full-time position to put it all into a nicely packaged open source framework called Scally, which I continue to work on.
Many times I’ve seen people take the attitude that non-UI developers can do UI development—usually when project time constraints come into play, comments like: “some of the back-end developers could jump on this”, “some of the designers know a bit of HTML and CSS, can they help you out?”, etc. I’ve always felt frustrated by this and at times I’ve felt this can come across as if UI development or writing CSS isn’t regarded or respected as a real skill, even though there is a team of UI developers. In my experience this just leads to annoying conversations about why it isn’t actually faster to have anyone dive in and write CSS—the time spent having to refactor poorly written CSS i.e. paying back technical debt, applying updates as details are missed, and potentially fixing UI breakages, just isn’t worth it. Just as I don’t expect to write back-end production quality code, the same vein applies to CSS.
Having generalist developers can work out in certain cases, for example, at a start-up where resources are limited and speed to market is crucial, or when UI developers are doing Style Guide Driven Development.
“Code reviews are really important.”
I find it quite frustrating to work in a team that doesn’t enforce some type of code review process like GitHub’s Pull Request (PR’s) process. A bunch of developers merging unreviewed code to master is risky business, it can negatively affect a codebase in many ways as well as the team’s dynamic, it can stunt personal development, and it goes without saying it can lead to more bugs making it to production.
I find for UI development work enforcing PR’s, for example: no code can be merged to master until at least one other person has reviewed it, is crucial. When you’re building a UI in a highly modular way you need to see what your team members are producing—I want to see a brand new component right away not when it’s too late, or even worse, after you’ve developed something very similar, or even the same thing.
Some benefits of PR’s:
- Keeping your codebase up to snuff with your code guidelines and architecture. Linting cannot catch everything.
- Keeping your codebase as lean and clean as possible.
- Personal development, for example, seeing how your colleagues tackle problems can be really beneficial.
- Preventing bugs making it out into the wild.
- Cross-team collaboration.
Even if people consciously understand that they are not their code, and that criticisms of their work are not personal, it’s still so hard to not be sensitive towards critique.
This is important to keep in mind when conducting code reviews within your team. I know I struggle with this and it’s something I have to keep working on.
“Code guidelines are really important.”
I’m a stickler for code guidelines as I think it’s really important to have consistently authored code especially when it comes to CSS as CSS can get messy fast—it needs all the help it can get, and especially when they’re a few of you working on the same codebase.
I want to be able to read code as easily as possible and not have to get my head around different flavours of code authoring styles. And definitely not have to waste time commenting on code that isn’t conforming to guidelines in code reviews (PR’s), for example, “these declarations aren’t ordered alphabetically”.
Most code guideline rules should be caught by a linter either locally or via CI, or both, leaving code reviews for actual proper code reviews.
Here are some good examples of CSS/Sass guidelines:
“Strive to bake accessibility and progressive enhancement into your UI development.”
I believe that accessibility and progressive enhancement should be baked into your normal day-to-day UI development workflow. So, things like:
- Applying semantic markup including appropriate WAI-ARIA roles, states and properties.
- Ensuring everything is accessible via a keyboard.
- Ensuring adequate colour contrast—even if this means going back to design/UX.
- Running your UI through a screen reader like Jaws, NVDA, or VoiceOver.
To me this is just part of the craft of UI development.
You don’t want to leave all of this until the end treated as an afterthought—which will take significantly more time—or even worse don’t do it at all.
In some countries, like here in Australia, you can be taken to court for providing an inaccessible website or application—see the World Wide Web Access: Disability Discrimination Act.
Some cautionary tales:
The Web has done wonders for people with disabilities, life changing for some, we should do our best to keep it as accessible as possible.
“Building a UI using real data in the application’s View layer or via Style Guide Driven Development really is the best way to work.”
Back when I worked at an agency I would sometimes build UI outside of the application as a bunch of static files, once complete those files would be tossed over the fence for a back-end developer, or even worse a bunch of back-end developers, to implement.
So many things are wrong with this process, to name a few:
- A lot of time is wasted! It doesn’t matter how well you document your front-end code, whether that’s inline with your code or using products like JIRA or Trello, things will always be missed, resulting in you spending a lot of time going back and forth with the back-end developer tasked to implement your UI—if you even have access to him or her. You’ve already wasted a lot of time by having to write documentation in the first place, and some UI developers won’t even bother. Throw interactive components into the mix, like tabs, accordions, drop down menu’s, etc. then things get really ugly. Rework, fixes, and frustration, will be inevitable.
- Suboptimal UI, basically general quality drops when too many hands are touching your UI code—you’re at the mercy of the back-end developer(s) tasked with implementing your UI, and when you aren’t building a UI in its final environment using real data then you’ll miss a lot of things resulting in brittle under-tested UI.
If I can’t work in the application building a UI in the View layer using real data, and getting the chance to take the task to its furthest possible point of completion—which might involve writing some lightweight back-end code like loops or conditionals—or being able to do Style Guide Driven Development then it’s not for me and I for sure won’t be able to do my best work.
“A Living UI Style Guide is so crucial.”
A Living UI Style Guide (LSG) is such a valuable tool to have and brings value to everyone in the business.
The “Living” part is crucial as inevitably a manually updated UI Style Guide or even a semi-dynamic one will eventually be neglected and fall by the wayside. This is not an easy thing to do though, both technically and culturally, and usually a LSG will not be high on the roadmap—if this is the case then do whatever you can to change that.
Being able to see and interact with an entire product’s UI in one place where you can see each components HTML and CSS, along with clear rules on how and where components should be used, allows you to build and design UI in a much more consistent, efficient, productive, and optimal way. Also UI developers no longer need to build defensively as a LSG allows for non-UI developers, for example, back-end developers, to put together UI easily in the application’s View layer.
A great place to end up is where you’re working in a team who’s sole responsibility is the maintenance and development of a LSG—known as Style Guide Driven Development. And not just the LSG but also creating and maintaining other front-end internal tools along with writing code standards and guidelines. Basically a team that enables all other feature or product teams.
Some of the major benefits of a LSG:
- Improved communication especially between design/UX and developers. A common vocabulary will begin to emerge.
- Cultural changes — everyone will start to think in terms of components rather than individual pages.
- Shipping new features faster.
- Simplified testing.
- Consistent and more robust UI.
- Prototyping new ideas.
- Cleaner codebase and reduced technical debt.
- More accurate development estimates.