Simple CSS methodology

suitable (but not limited) for Angular apps


“CSS is just coloring, typography, and layout of components on a web page
It is something simple. I don’t need to pay much attention to it.“

That is what many junior (but not only) developers (including front-end ones) think. I ran across similar statements many times. Moreover, I had the same feeling once I started my journey through the front-end jungle. However, now I think that one can’t be more wrong about CSS. And you will find this out in the first project that you’ll need to write custom CSS from scratch. I have been there and done that, more than once.

CSS is not simple
At the dawn, it was supposed to be used for styling text-documents, but it evolved and is used for more complex tasks.

Good news is, we can make it simple by following some basic rules.

In this article, I’ll try showing you how to write CSS in a way that will make it:

  • simple to develop
  • simple to understand & follow by other developers
  • easy to maintain

Just do it

To achieve the above goals, I have come up with the simple methodology of developing CSS that I use in my day-to-day work. 
Just to be clear: I know there are multiple, well-documented methodologies for proper CSS. Moreover, the approach I’m taking is based on those. To be honest, there is no wheel reinvention in my approach.

It’s just about making it simple.

The problem I have with the most popular CSS methodologies is their complexity. It takes a lot of time & effort to incorporate those into a project. And making sure the team is following those properly, consumes even more time. That is why I choose to take the essentials of popular methodologies and apply simple rules that cover 90% of cases. I noticed this works for me. In my opinion, at the end of the day, it is better to have something done than perfect but incomplete.

What is to come

This article consists of a description of the methodology I call: Simple-CSS. 
In particular:

  • what patterns it uses
  • what is prohibited (yes, by not doing some nasty stuff, you’ll avoid many problems).
  • how it can be used for styling app (however, the methodology is not limited to any framework, most often I use it with Angular, as components are building-block of it).

I’ll add some code snippets so that you’ll be equipped with all necessary tools for incorporating Simple-CSS in your projects. And you’ll be able to build some more sophisticated rules to extend the methodology, so it suits your needs. Let's get started!


Simple-CSS: the overview

First of all, it is important not to confuse CSS methodology with a CSS framework.

  • CSS framework consists of ready-to-use CSS code, that can be incorporated into your project. With an appropriate & reusable mixture of HTML markup with CSS classes, you can create a user interface without any custom CSS. There are many popular frameworks like Bootstrap, Foundation & more. Moreover, most of the frameworks are build with some kind of their own CSS methodology.
  • CSS methodology, on the other hand, is a set of rules that shall be applied to any CSS code that is being developed within a particular project. There is no code-base to incorporate. Its just making sure there are rules that are being followed by developers while implementing user interface.

Simple-CSS is a methodology, so, again, you won’t need to npm-istnall any package, its just a convention for creating CSS
The main idea is to follow a specific way of creating your CSS selectors and due to that, also markup.

Its about keeping your selectors: semantic, readable and flat. That means:

  • specific way of constructing class names
  • as few selectors nesting as possible
  • using only some types of selectors

For the purpose of thins article, let’s imagine we are building a football clubs application, that shall display given football club, with players and various statistics. It should look more or less like that:

Football clubs apps UI

This is just a mockup but will be good enough to describe Simple-CSS
In the context of Angular framework, it would be straightforward to create it with 4 basic components:

  • main-component a container section with nested components
  • search-component top section with logo and search box
  • clubs-component side section with a list of clubs
  • club-component main section with clubs details and list of its members

The functionality is simple and obvious: clicking club in the side section changes main section club details to the selected one. There is also search, that narrows down the side sections clubs list to fit given phrase.
Now, let’s take a look what are the rules in the Simple-CSS and how we would apply those in football-clubs app.


Rule 1: Component selectors are semantic class-names

Simple-CSS selectors are based on class-selectors. That means you’ll have to give a class name to any element that you want to style. And this class name shall be semantic, in a sense that it is meaningful.
In our case, for the club-component I would think of a class name like: 
.club-detail as the component displays detailed information, like players.
The second thing is following the dash-notation for class names. That makes it work nicely with sub-components classes (and is readable to me).

Common class pattern: .my-component-class-name

What we shall avoid, is the usage of id`s instead of classes. It is a matter of not mixing classes based selectors with id based selectors in your style files, what will eventually cause confusions across the dev-team. The second thing is the fact, that elements with the one id, like #my-component-id shall not be repeated in the markup. Id`s suppose to be unique, so to avoid a case when those are not, just stick to classes in terms of CSS.

Do:

  • use semantic class name for naming your components (it shall describe the component’s responsibility)
  • use dash-notation for class names: .my-component-class-name

Avoid:

  • using id`s for naming your components

Example:


Rule 2: Sub-component selectors are semantic and prefixed:

Sub-components are elements that create a parent-component. Those shall also be represented by a specific class name. This class name, just like with the parent-components, should be semantic. It should follow the same dash-notation. Moreover, every sub-components class name shall be prefixed with parent-component class name, separated with double dash.

Common pattern: .my-component-class--my-sub-component-class.

In the football-clubs app, .club-detail would be a parent-component, and we could create:

.club-detail--players for list of players sub-component
-.club-detail--club-info for club text information sub-component
-.club-details--players-single-player for single player information sub-component

Sub-components class names might become pretty long, but it will make those sub-components collisions resistant.

Collisions are one of the most common CSS bugs. I used to come across those many times before I started following CSS methodologies. They happen, when we have multiple sub-components with a common class-name nested in various components.
Imagine a .save-button class that is used for styling some saving data buttons (its a common name).

  1. We implement styles for 2 different-looking buttons in 2 different parent-components with cascade nesting
  2. If the second-component would be nested in the firsts one markup, and we would run into collision, as one of the buttons styles would get overwritten
  3. Hard to follow? Look at a simple example:
Simple css-collision example

One can argue that the just moving selector from line 13 to the end of the CSS file will do the trick and fix the collision problem, and its true. However imagine that your CSS bundle is 10000 lines long (not that hard to achieve), and you work in a team of 5 developers. Keeping track of what is moved to the end of the CSS bundle is cool? For sure doable, but I don’t think it is wise to spend time and effort on it… and there will be bugs.

So we should avoid non-prefixed classes names and also nesting sub-components classes (nesting also slows down the performance of our CSS, as the browsers read CSS from right to left, more about nesting to come). 
As with parent-components, id based selectors shall be avoided for the same reasons as mentioned earlier.

Do:

  • use only semantic class name for naming your sub-components
  • use prefixed dash-notation for sub-components classes: 
    .my-component-class--sub-component-class

Avoid:

  • non-prefixed, common names for sub-components classes
  • nesting sub-components classes in the cascade structure

Example:


Rule 3: Components and sub-components modification are semantic and statically-prefixed:

This one is the simplest. It is about modifying components styles in various situations. Most common example is the active state for marking selected components. In the Simple-CSS, we use an additional class that shall be added to the component in case of modification.
Again, it shall use dash-notation, semantic name and a prefix, just like sub-components. However, the prefix is way different than the sub-components one. It shall always be a single letter .m, what obviously is a shorthand for .modification.

Common pattern: .m-components-modification-state

In contrast to sub-components, this class shall not be used as a standalone class, but can be used only in conjunction with modified components class. 
In our example, we can see that clubs-component contains available clubs names list. In Simple-CSS, those are of course sub-components, so the class shall be called: .clubs-component--club-name. Now, we can see on the mockup, that the currently selected club has a blue background. That is a modification of original .clubs-component--club-name style, and shall be achieved with appropriate modification class. I prefer to treat such state as active, so I would call it: .m-active
One can think that .m-active class is common name and we might run into a collisions case. The first part is true, it is a common name, however at the same time its semantic: the element is indeed active (or could also be called i.e.. selected), but due to the selectors conjunction, it is resistant to collisions.
Take a look at the working example of modifiers:

The same markup, but classes conjunction make it resistant to collisions.

As with previous rules, we shall avoid different naming conventions, so there is no confusion to our teammates. Also, we shall keep in mind the fact that was already mentioned, that the browser reads CSS from right to left. This shall keep us from using more than 3 classes conjuncted, so we don’t run into performance issues.

Do:

  • use semantic class name for naming your modifiers
  • use static-prefix and dash-notation for naming your modifiers:
    .m-components-modification-state
  • always use conjuncted selectors for modifiers:
    .my-component-class-name.m-components-modification-state

Avoid:

  • non-prefixed, non-dashed, over-complexed classes names
  • more than 3 classes conjunctions

Example:


Rule 4: Keep as flat structure as possible:

We covered most of that rule while describing sub-components selectors. So we know that we shall avoid cascade not to run into collisions. Long story short: keeping the CSS structure flat.
Another thing worth mentioning is over-qualification of selectors. What does that mean? Basically, is about adding markup elements to our selectors. Every component that we make is related to markup element, like divs or spans. Over-qualification would happen if you would use both, markup element and components class name for building your selector:

div.my-component-class-name (don’t do this)

Such selectors are slower, so the performance of your styles will decrease, and moreover, you might start doing modifiers by swapping markup elements in your selectors, and that would for sure lead towards bugs.

Do:

  • keep flat structure of your styles

Avoid:

  • don’t over-qualify your selectors

Example:


General don’t`s

Except the rules and patterns that are described above, I always try to follow some strict rules that shall never be broken:

  • don’t use: * selector and its combinations, it is the slowest selector off all, and shall be avoided at any cost
  • don’t use: !important to any rules that you make. If you use it for fixing you styles bugs, that means you are not-fixing at all, just covering existing bug with an invisibility cape.

Working example

Here you can play around with the football clubs app, however, keep in mind its only very simple CSS developed with Simple-CSS methodology.


Recap

Just a quick cheatsheet for Simple-CSS:

  • all components shall have a semantic class name with dash notation
    use: .component-class-name 
    avoid: .componentClassName
  • all sub-components of a component should have a semantic class name, dash-notation, and shall be prefixed with the component class name and double-dash
    use: .component-class-name--child-class-name 
    avoid: .component-class-name-ChildClassName
  • all modifications to a component or sub-components should be conjuncted with component class, and statically-prefixed 
    use: .component-class-name--child-class-name.m-active 
    avoid: .component-class-name--child-class-name-active
  • preserve a flat structure of selectors (as few nesting as possible)
    use: .component-class-name--child-class-name 
    avoid: .component-class-name .child-class-name

That’s all folks! Please keep in mind this setup makes mine work easy. This does not mean its perfectly suited for all projects and workflows. Feel free to take what you find useful and modify this approach to your needs. 
Simple-CSS was brought to life by many people that I worked with, so special thanks to anyone who find his/her contributions here. It’s was always great working with you, even if we have conflicting views.

PS.

I hope you enjoyed reading this article, and also hope it will help you level up your skills. If you want to hear some more thoughts about front-end stuff don’t forget to follow me on Medium.