Product Design
December 5, 2018

Semantics, Semantics, And Semantics

In software development, semantics is the king.

“There are only two hard things in Computer Science: cache invalidation and naming things.”. — Phil Karlton

This is one of my favorite quotes ever. I don’t entirely agree about cache invalidation, but naming things is by far one of the most critical — and the most difficult — things in computer sciences.

“Naming things” means way more than you think. To me, naming things the right way goes all the way from simple variables, to CSS classes, to HTML elements, to whatever objects you are using in your OO language of choice. Naming things correctly, all the way from the bottom up, creates clarity and reusability. It allows for cohesive responsibilities and ease of maintenance. On the flipside, naming things correctly from the top down is usually a sign of good architecture. It means that your main components are doing what they have been designed to do, not more, not less.

Good naming is a sign of good semantics, and good semantics makes hard task of naming things easier.

To see this in action, let’s try an example using HTML and CSS. The idea is to generate the following awful screen:

We’ll follow two approaches to coding it.

Option 1 ( non-semantic )


Now let’s write some terrible SCSS code for this abomination.


If you’re an average engineer, the alarm bells in your head are probably screaming at you — and they should be. This is wrong in so many ways I don’t even know where to start describing problems: specificity, lack of standards, lack of semantics, terrible use of SCSS, unnecessary nesting, lack of responsive units, the creation of unnecessary dependencies between the structure of the HTML and the stylesheets, etc. At least, we didn’t write inline CSS in the markup. That could have been even worse.

All this is terrible, awful, and wrong. But unfortunately, it’s also very widespread.

Let me rewrite this using semantic HTML, standardized names, and good SCSS. It won’t be perfect — just a first pass — but the difference will be huge.

Option 2 ( semantic )


And some basics SCSS (that could certainly still improve upon):


Both codes have similar outputs ( I didn’t waste time polishing details), but they follow two completely different styles and philosophies.


Let me say a few terrible things about Option 1:

  • Where are the semantics? It is just a bunch of generic divs. Some of them have IDs, some have other classes, but is it easy to read and understand? NO.
  • Total lack of standards. Sometimes it’s using IDs (high specificity), sometimes classes, and the names alternate between snake-case, camel-case, or kebab-case without any criteria.
  • The code is not reusable, the concept of components (or object orientation) doesn’t exist here.
  • CSS structure mimics HTML structure almost entirely, which generates an intense dependency between both.
  • It uses pixels everywhere instead of more responsive units (like em)
  • Abuses the usage of identifiers in HTML elements.
  • Usually, “wrapper” and “container” indicates a lack of semantics and code structure.
  • Long and confusing HTML and CSS
  • High specificity CSS, which will never be reused. Also, if it has to be fixed, it will probably be rewritten with even more specificity, instead of refactoring the existing one. Typically, developers don’t want to deal with this mess. It creates a CSS snowball effect.
  • A bot won’t understand anything (not SEO friendly). And I could keep going…

So, after creating Option 2 of the same screen, we can see the following improvements:

  • Initialization of some basic general styles ([.c-inline-code]<html>[.c-inline-code], [.c-inline-code]<ul>[.c-inline-code], etc)
  • Usage of semantic HTML5 elements ([.c-inline-code]<main>[.c-inline-code], [.c-inline-code]<figure>[.c-inline-code], [.c-inline-code]<nav>[.c-inline-code], [.c-inline-code]<footer>[.c-inline-code], [.c-inline-code]<time>[.c-inline-code] ).
  • SEO friendly, standardized naming conventions
  • Semantic names (“company-info”, “services-list,” etc.)
  • Usage of responsive units like “em” and flex elements.
  • Semantic CSS and low dependency on the HTML structure.
  • If we want to change the properties of the navigation bar, we should only change some CSS properties. That’s why CSS was created in the first place, to separate semantics and styling.
  • It doesn’t have unnecessary nesting in SCSS, leading to a lighter CSS.
  • More general elements are specified first in the CSS, and then we go to more specifics.
  • We can read an element in the CSS, and we know what it refers to (navigation, list of services, etc.).
  • Both the CSS and HTML codes are maintainable and reusable

Unfortunately, codes like the first example are ubiquitous. I’d say that I see this kind of code every day on clients that come to Rootstrap looking for a rescue mission. We usually have to say that this kind of damage is not reversible, and it is way more efficient starting from scratch. We might lose clients being realistic and having high-quality standards, but at the end of the day, we are accountable for the code we deliver. If you’re not willing to do it right, sorry, we can’t work with you.

Semantics is critical. But if you break it down, it’s not that hard.

On HTML, list tags are for lists; navigation tags are for navigation menus, footer tags are for footers, header tags are for headers, sections tags are for sections.

On CSS, IDs are for things that appear just once in your whole application, have high specificity, and can’t be reused. Classes are for identifying characteristics and semantics of the elements. Everything has to be responsive. You have to design thinking about reusability and maintainability.

Semantics is the underlying principle that guides good code and architecture. And good names go hand in hand with semantics.

In software development, semantics is the king.

Feel free to drop me a line and let’s talk about how we can help you with better, more semantic software.