It happens all the time: you start a new project and everything goes smoothly. You have firm control of your codebase and productivity is on point. Then another project comes along, and before you know it six months have passed before you come back to that older project. Suddenly it’s not that clear anymore. What does this class do? What’s the type of this variable? Worse: now your colleagues have to build upon your work and you have a hard time giving them clear explanations.
This is a common problem in software engineering. We humans have great minds but terrible memory. As Scott Berkun puts it, “we have such bad memory that we forget we have bad memory”. Our brain constantly switches from one thing to another, and unless we have something, some trigger to get back on track, it requires a significant amount of work to get all pieces together again.
That trigger is called context, and fortunately for us, there’s a great way to implement it in our codebase.
Hungarian notation is a naming convention that consists of prefixing to indicate either type (systems) or use (apps). This may sound like an obscure and barbaric term for such a simple concept, but you’ve probably seen it before without even knowing.
The above naming convention is pretty widespread when using jQuery. Prefixing variables that store a jQuery object with a
$ makes it easier to know what it is a few dozen lines later. This is an example of type prefixing: the
$ tells us our variable is a jQuery object.
This does absolutely nothing to our variable though: it behaves the exact same way as any other. Also, prefixing doesn’t type a variable: you could have stored an integer there and it would work the same. Hungarian notation is by humans, for humans. If you do it wrong, your browser/compiler won’t insult you (but your coworkers might 😆).
_ tells us our variable is meant to be private.
_ prefix is here to tell you a resource was meant to be private, therefore probably can’t be invoked directly, and even if it does, shouldn’t because it might change or disappear.
A step further
c, presumably for
Do I need to prefix all my variables?
My personal opinion is no. Most of the time you can get away with a properly named variable, or short functions and methods (which you should strive for anyway). Clean code starts with expressive variables, and your job is to make sure these names are enough.
I still believe Hungarian notation is interesting for use prefixing (apps). Intended use isn’t necessarily something you can find out from a variable name or by looking around in the code. Type prefixing (systems) remains helpful for complex algorithms, other than that don’t overdo it.
Hungarian notation in CSS
There are many ways to keep your CSS under control these days. Methodologies like OOCSS, BEM or atomic CSS are great at abstracting rules into expressive and modular components. Besides that, architectures like SMACSS or ITCSS do an amazing job at structuring the building blocks of your CSS codebase.
Problem is, while CSS class names can tell you what kind of component they are, the role they play in the architecture of your project is a lot harder to define when you’re reading the HTML.
In this example, the responsibility of each class is unclear. If you’re not familiar with this codebase, it could be nerve-wracking and time-consuming to find out what to remove to disable a specific style, and what you can safely edit without breaking something somewhere else.
Namespaces, namespaces everywhere
I’m a big fan of Harry Robert’s (yet unpublished) ITCSS architecture. In ITCSS, you chunk the CSS codebase into logical layers. The three final ones is where we define actual classes: objects, components, and utilities.
- Objects are abstract, undecorated, structural elements. They usually can be reused from a project to another, and are used to build actual styles upon. You may need to add modifiers, but an object usually is immutable. A
.media-elementclass that puts an image and a text box side by side and make them use 100% of the width, or a
.listthat removes bullets and left padding, are good examples of objects.
- Components are concrete, specific UI elements that define the look and feel of your design. Some components are independent, while others may rely on objects. A
.buttonis a great example of a component.
- Utilities are small rulesets that help you either build a larger component (that’s especially true if you’re using an atomic CSS approach) or override styles from higher layers. Utilities usually don’t have abstract names like objects or components, but are rather named after their function.
.text-centerare typical utilities.
Let’s use Hungarian notation on our classes: objects will start with
o-, components with
c- and utilities with
u-. From there, this is how our HTML would look like:
That’s much easier to read. Now we know at a glance what each class is responsible for. If you need to change the order in which the image and text content are displayed, you’ll add a modifier to the
.o-media object. If the background color has to to change, it will be applied on the
.c-card component. Finally, if the box-shadow needs to go, you’ll remove the
Harry Roberts dives way deeper into prefixing methods in his own article More Transparent UI Code with Namespaces. I strongly encourage you to read it (and everything Harry wrote) if you’re serious about building robust CSS architectures. There are some pretty interesting prefixes in there, such as
qa- for automated functional testing with web drivers like Selenium.
Do I need to prefix all my classes?
Use prefixing doesn’t only give you back that lost context, it also enforces the methodology and architecture you picked by making it more visible and explicit. You have everything to gain by trying it out.