New post - 'An intro to agile for new devs'

The core of my skillset is front end, including expertise in React, page load performance, accessibility and authoring UI component libraries. I also have 8 years’ solid experience of Node.js.

I understand every angle of a successful agile team including user-centred research and design, continuous delivery, TDD, test automation & strategy, pairing and shared ownership of quality and dev-ops.

I have skills in:

React

scalable CSS including CSS-in-JS

Node.js

Javascript

Typescript

page performance

accessibility

micro-services

micro-frontends

progressive enhancement

TDD & unit tests

BDD & end-to-end tests

responsive / mobile web

CI / CD

agile

rapid prototyping

Scalable CSS

CSS is uniquely misunderstood among the main front end technologies. Not to say it’s extra complex and requires a larger brain to understand (luckily for me), just that normal rules of programming don’t seem to apply. There’s no logic problem to solve or unit tests to write and guide the process. The ease with which CSS can be churned out leads to unmanageable codebases in short order.

Javascript testing tools have gone from a standing start six years ago to a high level of maturity now. You can refactor with confidence, and aim for quality abstractions early, or you can wait - your testsuite will have your back as you identify opportunities for reuse and rework the code heavily, knowing you can be alerted within seconds if something went bang at the unit or integration level.

CSS doesn't have anywhere near this degree of protection. You have little guard against regressions as you refactor, apart from manually eyeballing pages after a change, and maybe automating screen capture diffing to try to catch if UI components don't visually render as they should. This lack of cover can lead to a certain mindset when many developers work with CSS.

In my experience, many developers are as wary of a CSS codebase as a bad pub toilet - they really don't want to go in there, but at some point they're going to have to, and when they do they want to touch as little as possible then get out quickly.

As there are no tests to notify a developer if they broke something, their number one priority becomes to minimise the chances of breaking something. This is completely understandable but usually at odds with other goals such as code reuse.

Fear of breaking something leads to creating highly specific selectors which are tightly coupled to markup structure to minimise the chances of affecting any other element:

#footer .nav-items > ul > li > a { ... styles }

You're almost certainly not going to break anything else on the page with that selector. But reuse becomes harder. If you later want to apply those styles to another part of the page, you could add another selector:

#footer .nav-items > ul > li > a, #header .mainNav > ul > li > a { ... styles }

This isn't going to scale much further, and is very fragile - if the markup structure changes, it breaks. If the inner markup pattern is moved to elsewhere in the page, it won’t carry its styles with it as they’re so tightly tied to its previous location.

Better to have a simple reusable class and just add to the HTML, then you don't need to write any more CSS each time you want to reuse it:

.nav-link { ... styles }

But this refactor is often never made due to the reasons given above.

As it's harder to defer the process of refactoring out common code, the key to scaling CSS is to code for reuse from the very beginning. Earlier than with ‘normal’ languages, for which abstractions can emerge.

Aggressively pursue code reuse from the get-go. If in doubt, assume that reuse of a given visual pattern will happen, rather than waiting for proof before abstracting it. Designers obviously have a role to help with this in pointing out where visual patterns are, or will be, repeated.

To encourage discoverability and reuse, name classes based on functionality and appearance, not context. A '.job-card' could well share most of its styles with a .resource-card - why not just call it a .card, and extract the differences out to granular subcomponents that can be recomposed and reused in different contexts. Make that assumption of reuse early - don't wait too long - CSS codebases can grow and rack up technical debt so quickly that the likelihood of ever clearing it diminishes.

Keep specificity low - selectors should usually have one class only. Don't use tag names in selectors, it couples you too tightly to markup patterns and makes the class less reusable - you might want to apply a link style to either a <button> or <a>.

Avoid styles leaking in and out of your component by using a convention like BEM, which also helps with the age-old problem of 'what do I call this?' and makes components much easier to pick out from a morass of page markup - every class used in a component has the same prefix - .card, .card__title, .card__description. Simple yet powerful innovations like BEM have been so gratefully received by developers and are so hugely popular because they help bring sanity and organisation to chaotic CSS codebases.

Place your card component's SASS file next to its corresponding HTML partial or React component in your folder structure to emphasise their coupling and improve discoverability. But don't bundle the CSS in with the Javascript using something like Webpack - it's a performance antipattern. CSS should be loaded as soon as possible as it's on the critical rendering path. Javascript isn't required for the initial render, or at least shouldn't be, and can be deferred.

jonnywyatt2 - [@] - gmail.com