As a developer, when it comes to build my own application, I always have the tendency to borrow UI design from other websites or simply to work with design created by someone else, like a designer.
I never cared about design concepts such as colors, fonts, typoghraphy, emphasizing techniques, hierarchy patterns etc..
I used to think that Designing and Implementing an UI were 2 separate world that which must be handled from different roles (a designer and a developer).
Well i was wrong.
Recently i came across a book called Refactoring UI written by the creators of TailwindCSS (shout out to them).
That book changed my idea of just being a developer who is only capable to work with pre designed UI to be a developer who are able to design his own UI.
If you are like me and never approach before the concepts beyond UI / UX design and only cared about how to implement an UI with the latest frontend framework, I highly recommend you to read this book because is full of insights made specifically for developers.
While reading this book i came across with 3 useful designing tips which i'm sure will benefit your journey as a frontend developer dealing with Design.
Let's see them.
Every time i start working on the design of a brand new application, i used to always start implementing first the layout of the application.
So i generally start thinking about whether to choose from a top navbar instead of a sidebar, how to display the navigation links, whether to choose from a container layout instead of a full width layout and so on.
Well let me say that this approach might be not the best, because at this early stage of development we are lacking of informations
Especially if you are on your own and don't have an UI design to follow through, a better approach will be to start implementing first some basic features of your application.
For example let's say i'm working on an hotel booking platform.
Following this approach, the first thing that i would start implementing , will be a feature that will permits the user to search for an hotel.
In this case i would start to laid out a form where the user can fill out:
- the place where he will stay
- the check in and check out dates
- the price range
- the numbers of bedroom that he needs
- and a search button
After that i get my input search functionality, i could start working on a new feature, for instance the result list of hotels that the search has found.
In this case i would need to implement a list of hotel preview template where each one will have:
- an hotel image
- hotel’s address
- hotel's price
- and the button to send the reservation to the hotel
Only after having implemented at least some basic functionalities around my app, i could start caring about things like:
- how to manage the navigation between these pages
- choosing from a navigation bar or a sidebar
- implementing a footer
- or where to place the application logo image
In this way i would have much more information about my app functionalities and therefore i will make better decision when it comes to dealing with the layout offered by the application.
Remember when it comes to design an user interface we often have to take important decision in order to achieve a great user experience..
So the more information we'll have on our side the better decisions we'll make
In the earliest stages of designing a new feature like the hotel booking search functionality, it’s important that we don’t get hung up making low-level decisions about particular details like colors, font styles, shadows, icons, and things like that.
In particular I identified 3 cases in which i personally tend to spend too much time, early on.
This is particularly annoying, because I basically start spending time on trying to figure out what color could be the best suit for a background or a text, up until i find one that pleased me off.
Unless you have a color palette already set up for you app design, a very simple trick that i usually follow to not fall into the trap of colors picking is starting with grayscale colors.
When i don't know what colors to choose for a particular element, i just fallback on some shade of gray.
Later on when my feature will have all the components that it needs, i could start enhancing it with a specific color already in mind (hopefully).
This means starting implementing early on the interactivity parts of a feature, things like button handlers, scrolling effects, form submit, etc..
These are very time consuming tasks which often requires to implement some sort of state management pattern around or some sophisticated algorithms for implementing things like parallax effect..
Not to mention that these are the main source of bugs when it comes to developing an UI.
The trick here is to implement first a static mockup of your feature and, only later on, start to adding all the interactivity parts.
This means to start thinking about particular edge cases that could affect your feature.
How should the design looks like if the search has no results or if it generate too many results ?
What if a particular hotel has all rooms already reserved ? Should i display a disabled Book button or don't show it at all ?
These are important decision making situations which you often experience only when you start diving into the various scenarios of the features you are taking on.
What i generally suggest in this cases is to simply annotate the edge cases which you encounter while working on your feature and simply handle them later on, when you'll have all the necessary informations to deal with them.
So these were only just some of the common cases where I generally start to worry about details early on.
The main takeaway here is to avoiding designing everything up front.
Usually i like to follow a more iterative approach where i continuously switch from a Design phase to an Implement phase.
Essentially i start by designing a small piece of my feature and then implement it, then back to designing another piece and then implement it as well.
I repeat this process iteratively until there are no more issues left to solve and i'm happy about the result that I achieved.
Whenever I start working on a big feature (such as a Chat system, for example), I usually divide the feature into several subtasks to which I assign 2 possible priorities
- Nice to have
For instance, let's say that i'm working on a chat system.
The required functionalities of this chat are essentially:
- the area to display the chat messages
- the textarea to type the message
- the button for sending the message
But at some point i start realizing i'd like the users to be able to send images or videos inside this chat, so i decide to include also an attachments section in my Chat required functionalities.
I got deep into the implementation of this functionality only to discover later on that supporting attachments is going to be a lot more work than i've anticipated
In fact i'll need for example to manage all the process of a uploading a file, which can be not so easy to implement.
Now, If I was working on other tasks in the meantime and suddenly discover that one of those task require an higher priority rather than my chat system, i soon realize that i won't be able to ship my chat on production due the lack of this attachment functionality which is currently not completed.
So I went from being able to get a simple working chat ready to use, to not having a chat at all due to a core functionality missing (the attachment part).
As rule of thumb, to avoid these type of situations you need to always design the easiest version you are able to ship.
If part of a feature could be considered as a “nice-to-have” functionality then it could be designed and implemented later on.
In this case the attachment functionality can be safely marked as a "nice-to-have: functionality, so it may be added in a future version of the chat system.
Following this approach, can also increase your productivity, because you will be able to ship more basic features rather than 1 or 2 complex features at the time.
So here it’s important to remember to always design and implement first the easiest version possible of your feature.
So that's it! These were my top 3 tips that i wanted to share here today with you.
One last thing that i'd like to add is that the main ideas around the concepts that we have been discussing so far, is that they can be safely applied to other fields of software development or Software Engineering in general.
Whether you are a backend developer, a solution architect a designer or whatever, i'm sure that if you'll be able to apply those simple rules in your day to day job, your work will come much much easier.