I’m a software engineer living and working in London. In my daily work my primary tools for the web are React, Next.js, GraphQL and Emotion for CSS. In my personal projects, I often play around with different technologies like Gatsby, Svelte and whatever else looks interesting at the time. I don’t often get the chance to write plain HTML and CSS. It’s not that I avoid it but it just never seems to be part of my workflow like it once was. I decided to take a step back and start a project with the core building blocks of the web, it’s been a novel experience.
When you get used to something like React, it becomes comfortable, it becomes the de facto tool for the job. Need a new blog? Use Gatsby. Want a marketing site? I’ll use Next.js. Need styling for a quick admin interface? Take your pick of CSS frameworks and/or component libraries. There’s a plethora of choices, a tool for every job that all fits into the React ecosystem and more broadly, the ecosystem of the web. To ignore that for a moment, however brief, is a breath of fresh air. To forget all of it and go back to basics, to code like the early web, it’s liberating.
So, why did I do it? I wanted to try out variable fonts and I didn’t need any reactivity, I just wanted to tinker with a static webpage. That’s why I avoided Create React App. I avoided all of the tools I’ve relied on over the past 5 years and just did it. This is what, I discovered along the way and a few reasons why you might want to give it a go every now and then.
I left this all behind to hand-craft some CSS. Here’s what I learned.
Working in the browser’s dev tools is great. The developer tools from Firefox, Chrome and Safari are excellent. The best part is that they just come with browser. There’s nothing to find, add and configure unless you really want to. CSS is one of the primitives of the web and dev tools can make working with it a dream. My favourite feature is the ability to live edit your CSS with workspaces. Changes made in dev tools are synced with your project on your filesystem. It’s almost like an evolution of Dreamweaver for the modern era. You can inspect gradients, create box shadows without trying to remember which order values should be in and all from within the browser. It’s the ultimate WYSIWYG, there’s no guessing what your page will look like - you’re editing it live, zero delay.
One downside of editing your CSS by hand is the lack of auto-prefixing. With every year and every new release of browsers, this is becoming less relevant. Browser support in a much better place than it was a few years back and the majority of what you need to do is supported. Jumping through hoops to get a nice developer experience with modern tooling feel antiquated when a great solution already exists. It might not meet all the needs of browser compatibility out of the box, but the experience is great and the feedback, instantaneous.
It feels unfamiliar writing plain HTML again. Years of React has made me forget some of the differences between JSX and HTML. Writing
class instead of
className feels out of the ordinary. I had to delve into the recesses of my mind to remember the proper way to link a stylesheet; when you’re doing React, you’re often used to a transpile step and more likely to add CSS to the build chain. These little differences throw you off for a while as you re-acclimatise to that estranged markup language.
The most refreshing thing about writing HTML from scratch and CSS from scratch is the separation of concerns. I miss it. Writing markup in one file and how it looks in another, loosely coupled with class names is great. The product I work on professionally uses Emotion, which means styling is added directly to the element and is pulled into the head of the document on build. It’s useful in some circumstances and isn’t as noticeable when hidden away in reusable components but it’s always present. When parsing code, looking at the semantic structure isn’t as easy when styles are essentially inlined for the majority of elements. Your markup, styles and logic are smooshed into a Frankenstien’s monster that we call a React component. There’s also a gap between what you write and what’s produced, a class name is automatically generated for each element so tracing a style from a production build back to the source can be challenging.
A separate CSS file and HTML file make it easier to parse both files. It’s just more readable. It’s not necessarily the best method for a component based frontend but a lot of webpages, it works so well. There is some back and forward when inspecting classes in HTML and the implementation in CSS but it’s nothing that can’t be eased by using dev tools or a split editor.
The most fun from not using CSS is the constraints it adds. Constraints make the most interesting decisions, they force you to think with the tools you have and push the boundaries further than you normally would. Setting myself an artificial constraint of not using JS was fun because it forced me to use CSS for animations and focus on the look and feel rather than functionality. You’re not tempted to add additional libraries because you can’t. You’re not attempting to manage state within a component because there is little to no state. Constraints give you a framework to work within, to the push the limits of and to embrace.
Should you stop using modern tooling, throw caution to the wind and code like it’s 1999? Probably not.
Modern tooling gives us superpowers for manipulating the raw elements that make up the web but it’s a layer of abstraction. That’s not a bad thing. The modern approach to web development takes some of the tedium out of frontend development. It’s allowed us to move faster than ever before and create experiences which are feature rich and delightful to use on more devices than ever before. Having said this, sometimes it’s nice to have a break. Everything is a tradeoff and sometimes it’s nice to revaluate. It’s a breath of fresh air to just sit down and whip up a simple webpage without ever waiting for a build step. Never installing a package via npm. Having full control over the output.
It takes away certain decisions like which package manager to use, how to bundle assets, which CSS-in-JS method is the best. It adds constraints. You’re not thinking of what package could solve a problem, you’re tinkering directly with the web and working with its quirks and limitations. It’s not bad or good, it’s just different. It harks back to times where we had different problems and different concerns.
I challenge you to go out of your comfort zone and give it a go. See what it’s like to code from scratch in 2021, you might learn something new or gain an appreciation for how far we’ve come.
If you enjoyed this and would like to read more articles like this as soon as they come out, check out my blog.