Frontend Engineering Strategy

Jon Hadden
6 min readFeb 15, 2022

The technologies powering browser-based single page software applications are evolving at lightning speed. It seems like every year a new frontend library, or new version of a frontend library is released with all new syntax and methods to manage state, store data, and segment code into smaller chunks.

Many of the advances have been amazing with regards to performance, managing security, and testing our code. Component-based frameworks have made chunking our UI’s into smaller, more manageable pieces of code and make building scalable applications extremely simple (relatively).

And yet, while all of the Javascript syntax keeps changing and evolving, we keep writing bad HTML and CSS. And because of it, new CSS frameworks come out to address the bad code engineers have been writing, only to create new messes.

If it ain’t broke, don’t fix it. CSS isn’t the problem. It’s an inability to understand how to write it well.

Without semantic HTML or CSS that properly uses inheritance or cascading of styles, it makes responsive, maintainable, and accessible software applications nearly impossible to build.

Now, there’s nothing wrong with using frameworks like Tailwind, Bootstrap, et al. They allow for rapid development out the gate with developers of varying experience writing good frontend code all around. But if you have the people to roll your own design system, it’s probably a good way to go.

Everyone has opinions, but here’s how I would define a good frontend strategy.

Start With Accessibility Front and Center

Too often, accessibility is an afterthought when ripping through new features and tackling bugs. The simplicity of finding a modal plugin that works for your tech stack, running a quick npm install and propping up the functionality the design calls for, is sometimes rather trivial these days.

Taking the necessary time to capturing the event that triggered a modal to display, trapping and handling focus within elements, and properly resolving once closed is a whole new ball of wax. Developers aren’t versed in it, so it left out of the implementation until compliance forces a certain level of WCAG standards. Modals and custom dropdown menus are usually the ones that blow accessibility out of the water, but so does not using simple things like alt and title tags, or semantic HTML. Which brings me to my next point…

Write Semantic, Simple HTML

When writing HTML, ask yourself what is the best way to represent the data that this element is supporting? Is it a definition list of titles and the data that it represents? Is it an article with a sidebar of related content (aside)? Is it an ordered list? Is it something that the user takes action on and clicks to perform a function? Or take the user to another route?

Each one of these examples above, has markup to support the meaning of the content.

The idea is always, no matter what, use the semantically correct markup for what that element is meant for. This will go a long way to making your application not only WCAG accessible, but also ensure only writing the minimal amount of code necessary. Keeping it nice and clean.

Using <div>’s for everything and putting onClick events on everything from <span>’s to <p>’s are probably the most egregiously abused examples of markup. Please don’t do it, but if you must, use ARIA labels to describe the content.

A good reference for semantic HTML is of course, the MDN documentation:

Keep Sass Simple, Easy To Follow

Write maintainable styles. Sass helps you out with writing clean CSS. It’s not a framework, per se, but it is a way to write styles before a light preprocessing into CSS. Out of the box, it is filled with a lot of awesome functionality. It does a lot of things.

A LOT. OF THINGS.

Too much if you ask me. One over-ambitious Javascript engineer trying to prove their CSS chops, and it can get very complicated, very quickly. In the same vein, abandoning CSS for a utility-first style framework, such as Tailwind CSS, that changes everything to be more complex and will ultimately create an unnecessary abstraction from the simplicity that CSS and the separation of concerns aims to provide.

The best CSS, is simple to follow. Easy to understand. Fast to maintain. Selectors are only as specific as they need to be. Don’t over think it. CSS doesn’t need to be fixed. Don’t abuse it and you should be fine.

SASS features I tend to use frequently:

Global Styles with @import

I always have a global CSS file that includes various things that are needed at a global level. This commonly includes CSS Reset, Global HTML styles, Typography, Grids, and Utilities. Things like buttons and form elements may be better suited for component-level styles.

Variables & Mixins

A variables file that contains commonly used colors, measurements, and elements styles that are applied in many places throughout my component level styles.

A mixins file that works very similarly to the variables file. Responsive media queries and common blocks of styles that are used and can be applied in various component-level styles. I usually keep this rather light.

Nested Styles

Nesting of styles is probably my favorite SASS functionality, but makes me the most nervous. When done gently, it can keep your code nice and clean, while still giving you the specificity needed to create a well-defined scope of a selector.

When nesting styles, make sure to take a lot of care not to abuse it and have nested styles because you think everything needs that specificity. Commonly, you only need one level deep, if at all.

Component Level Styles

Component-level styles accompany the HTML and JS for the component. It’s specific to only the component but may use some of those global variables or mixins along the way.

Write Better Selectors

Writing better selectors improves HTML cleanliness and simplifies CSS.

When you feel the need to add another layer of HTML elements or adding another CSS class, ask yourself if there is a pseudo selector or a way inheritance of a single class would work.

I’ll keep this one brief. This above example, happens all the time at the hands of very, very, senior engineers. So you accept their code as good. But it’s not.

A mentor engineer of mine, Jamey Lazarus, once said to me “If you ever see something repeated in code, that’s a good place to improve it.”

He was referring to JavaScript at the time, but I think it fits nicely with choosing selectors. More often than not, I’ll see something like below. Where the CSS will have a .tile class that has styles, the .til-list will also have styles as well.

But this can be simplified to using only the .tile-list selector and direct-descendant combinator. .tile-list > li { my tile styles go here }.

No need to add a class for each list item and removing them cleans up the code rather nicely.

Start Small and Work Your Way Up

Assume every design you work on has some adaptive or responsiveness applied to it, even if the designer didn’t design it on the first pass. Unless research shows the product you are building will only be used at a certain browser resolution or size, Product will always prefer to have a responsive application than not. Designers sometimes, but don’t always think how the structured HTML, both at the larger grid level and smaller component level, would be handled across various browser resolutions. And how could they?

Unless designers are spending enormous amounts of energy and time building responsive designs in Figma, they’re usually sending static mockups over the wall with a representation of a few browser resolutions. Which is totally fine. But the responsive design work is just get started at that point and you’ll need to be ready to make some design decisions and/or frequently hold conversations with your designer/product friend. Which should happen anyway.

Regardless, out of the box, the web and browsers are responsive. Everything had fluid width. Use that to your advantage.

Frontend engineers, for the love of all that is holy, write your CSS and HTML from the small size first. Start increasing the browser width, and when the design looks like shit, that’s a good spot for a breakpoint using min-width.

Write your CSS from the smallest size first and use min-width, and you will be rewarded with much, much cleaner CSS. Way easier to maintain.

Not only do we have media queries at the moment to help adjust UI’s in various screen resolutions, but the proposed container queries are making waves and are a great way to manage things on a micro level within a component-based framework. However, support is rather scant as of writing this, so I’ll stop short of saying this should be part of your strategy.

Some Useful Links & Resources

--

--

Jon Hadden

Frontend Engineer, Information Architect, Father, and Dog Owner