Obviously, it is best to involve design from the start – and I think a lot of advice is made for such projects and many designers want to work in such projects. However, many (if not most) projects develop from smaller hacks that grew more than expected and then notice – better late than never – that they might need to improve their usability.
It is easy to tell what they should have done and what a better structure would be, but that would often mean major code changes that would take a long time – if they happen at all.
What I would like to do is collect patterns that are particularly well suited to improve usability of existing software without immediately requiring large changes of the code. Here are some that I thought of:
Review lables – Text is usually easy to change, as it often already exists separately from code and a lot of the user’s understanding hinges on having picked the right lables for commands and objects.
Review Icons – I know, icons again, but they are also relatively easy to change and sometimes existing icons are shoehorned into features or icons were designed on a large screen and than scaled down beyond recognition.
Review/use help texts, tool tips and documentation – I feel these are seen by designers as “it needs to work without” and thus as a crutch, but it still can be very helpful.
Ensure that the software can be easily installed – This is not the most fun kind of programming (dealing with different platforms and their sometimes changing requirements) but it a problem often solveable in code that can remove major barriers somewhere on the “compile it yourself” to “click and run” spectrum.
Prioritize functions – Existing UI elements can be reordered or redesigned, so that the ones for standard use cases are easy to find. A conscious decision here is occasionally seen as too prescriptive, but an unconscious priorization or non at all is equally prescriptive for how to treat the software
Meaningful initial state – When you start the program, it should be clear which actions you need to do next. A “New document”, “select files for conversion” or whatever is needed to use the program’s main functionality should be very obvious to access and find.
Configuration – If possible choose defaults that work for most users but can be changed later instead of requiring everyone to make these configurations themselves before they even know the software. If there is unavoidable configuration, guide the user through it and make suggestions.
These might be band-aids but they are better than nothing and might show the usefulness of design to justify larger changes later.
…do you know more fixes for applications that grew without a designer?
This is great advice and an excellent idea. Do you have a vision on how to share this with the world? Create a collaborative document (e.g. using HedgeDoc) to work on something that can be shared easily with projects? I would love to help, although my time is rather constrained for the near future.
Forgejo is doing some of the mentioned things successfully, such as fine-tuning menus for clarity and consistency. It is not large refactoring, but makes the software easier to use and more accessible every day, and it can be easily distributed as “good first issues” (compared to working on bugfixes and new features - at least for people who are not familiar with all the technical bits of the software).
I would probably turn it into a blogpost at my website at some point. If people contribute, I would cite their contributions. So far I have no plans to turn it into a collaborative resource outside of this thread, since it can become very unwieldly over time (adding is easy, editing is difficult) which makes it hard to use for readers in the end (I would not mind anyone using my points for building such a resource, though!)
Ok alright. I don’t really have a pattern to add, but my suggestion for projects or individuals getting started with usability is: watch users.
You might not notice what is wrong with your {icons, labels, defaults} until you see someone struggling over them. Even when you think to know what needs to be improved, it can be opening your eyes and give you different priorities.
Even if you don’t analyze a session in detail, it might give valuable insights and is not be too hard. It would definitely be on my list of recommendations to get started easily.
What might be an interesting addition is how to refactor code in a way that it allows to make design changes. I guess a very common move might be moving towards doing data changes via commands that could be triggered by the UI and also moving out of smart UI patterns. I.e. getting software ready for UI improvements also often means improving code quality in general.
Hmm, I’m not sure about the backend refactoring, but when it comes to the frontend only, I really like to insist on semantic markup and styling to create consistent experiences.
Think about the semantics and style later: It often makes the code more reusable and changing the styling changes it in all places (without the need to touch the HTML, for instance).
Look at different parts of the app (e.g. different menus) and compare them. Are the differences necessary or could a refactoring help deduplicate the code?
Focus on semantic rules instead of colours.
The third point can be a delicate topic in many places, because there are different philosophies. I feel like I should elaborate more here. When it comes to a consistent user interface, I think this is very important.
If you define buttons and style them e.g. using “large red”, you’ll have to think about it each time.
If you style a button as “danger” or “destructive” it makes it much easier to give consistent stylings to such buttons from a single place. To illustrate the button example, take a look at this Forgejo issue where I wondered about the three teal buttons and their meaning. But the same really applies to everything.
Another example with headings
In many frontend frameworks, developers would probably style headings using CSS classes like ui top attached primary header full-width or even more complex constructs. It’s quite likely to miss something over time, and refactoring the styling would either mean updating all of them at once, or introducing inconsistency.
Here, I would suggest something simple such as this:
Styling would apply so that all headings (and other elements) inside settings look the same.
And in another app of mine I dared another experiment: I forced styling of buttons on the environment. In this example buttons only get “red” when they are either inside a confirmation modal, or if they link to a confirmation modal - there is no other way to create a red button. Although I would prefer to allow undoing operations, I found this a very simple trick to prevent me from inadvertently creating a “red” or “danger” button that does not have a confirmation prompt and reinforce the consistent behaviour through the styling.
@fnetX good point – I was thinking of good old fashioned desktop applications and OOP (mentioning “smart UI” and such). Web applications already enforce something similar by the need to send requests to the server (That can be done in ways that lend themselves better to encapsulation and maintainance…or not).
To illustrate the button example, take a look at this Forgejo issue where I wondered about the three teal buttons and their meaning.