Replicating the Medium Website Using CSS Molecules

The perfect balance between CSS Zen Garden & Tailwind CSS

Joana Borges Late
JavaScript in Plain English

--

Adapted from the album Crusader — Saxon

In the beginning, the gods wanted to help the communication among people. They created the HTML. And the humanity felt that it was simple and good.

After millennia (3 years, actually) the gods decided to bring the web to life and whispered winds of JavaScript on our planet. And humanity danced with joy and enthusiasm. And ingenious human beings started to work hard and fast, and soon the gods were amazed at the wonders of the browsers running the new webpages.

But the gods felt sorry for the humans who were struggling to do their jobs with very bloated HTML files, where element tags were overloaded with code for presentation (color, font, layout, decorations…).

The gods realized how hard it was to edit a so bloated webpage and decided to gift the humanity with a golden apple called CSS. Unlike the biblical story/history where the humankind was forbidden to bite the apple, here the apple was meant to be eaten, as long as the humankind respected the eleventh commandment: The Separation of Concerns.

Our high priests started to spread the celestial knowledge: HTML for structure and content; CSS in separated file(s) for presentation.

The most faithful and selfless priests assembled in a place, that today is known as the CSS Zen Garden. And swore to devote the rest of their lives to The Separation of Concerns, catechizing every other human being (web developer) to the adoption of their beliefs in the most pure form. Everybody should follow THE ROAD TO ENLIGHTENMENT (this text in caps lock I ‘ve just taken from their website, it is the first header there).

Well, you know how humankind is. If among angels there is rebellion, fallen angels, imagine among human beings. Some people could not strictly adhere to the Separation of Concerns, deep in their hearts it did not seem to be their true faith.

That was how the holy war started.

Many had stand against the Separation of Concerns, many fell on the way. The most prominent warrior to survive (greatest heretic, if you prefer) raised the house named Tailwind CSS.

This is the moment we are living. Both factions have equivalent strengths. There is no sign of the end of the war — be it by peace or by victory of one side over the other.

If you are new to this land, take good care, because both sides are very seductive and have ancient, very powerful charming rituals (clever rationales backed by special samples in their home pages). You may easily drown in an ocean of dogmas.

And the gods?

Well… who can stand a holy war? The Gods looked down and said, “The humanity sux. Let’s move to another galaxy.”.

Admiration and respect

I want to express my admiration and respect for the folks behind CSS Zen Garden and Tailwind CSS — among many others. They have created their own space in the web development.

The fact that I dislike and/or disagree with some or many of their decisions doesn’t change how I feel about them.

Also, I respect any developer, no matter the way he chooses.

That said, I will allow myself one joke or another.

Real code. No dogmas.

Last week I had a chat with a reader that made me realize that without real life code we cannot truly understand each other. He was criticizing what he imagined I had proposed. Not, what I really proposed.

Please, don’t come tell me “that is not how HTML/CSS is meant to be”, because I have my own belief about it. The web is meant to be good and simple, like the gods made it in the first day.

“But you are going back to HTML 3.2!” — No. I only write W3C validated HTML5 (and CSS). And if here and there the code resembles the past a bit, is this a problem? Windows 10 returned to Windows 7 (roughly speaking) because Windows 8 was SUCH a crap. Before, some users used to replaceWindows Vista by its predecessor, the Windows XP.

“But you are using presentational classes…” — I don’t care!

What I care about is

  1. short, simple, readable, maintainable, fast to write code and
  2. fast, always good-looking, accessibility friendly webpage.

I am used to listening to PageSpeed Insights.

Molecular CSS

Molecular CSS is not a JavaScript framework. It is not a software or any kind of tool. It is just the set of basic rules that were born, one by one, day by day, in my journey away from the Zen Garden.

These basic rules are about the structure of the CSS code itself. In case you are interested in layouts, I suggest Solving All CSS Layout Issues.

The current article is as very improved version of my previous article, Finally, I’ve Mastered Trivial(?) CSS.

The benefits of using Molecular CSS:

  1. small code
  2. very readable code
  3. very reusable code
  4. very maintainable code
  5. excellent productivity

The disadvantages of using Molecular CSS:

  1. the Children Of The Zen Garden will stalk you for the rest of your (short) life

We will return to Molecular CSS later.

The *HUGE* issue in CSS

"use strict"

var color = "white"

function makeColorRed() { color = "red" }

function makeColorBlue() { color = "blue" }

function main() {
makeColorBlue()
makeColorRed()
console.log("Color is now", color)
}

main()

As expected, the JavaScript program above prints “Color is now red” in the console.

Translating this program to any other programming language (excepting CSS), the result is the same. The order of the declaration of the functions doesn’t affect the result (excepting when a function overrides a homonymous function).

For all programming languages (but CSS), what matters is the order of the calls to the functions.

This article considers that HTML and CSS are in the realm of programming languages, in the broad sense. They belong to the “declarative” branch. Anyway, it is purely theoretical.

Now let’s translate that program to HTML/CSS:

<!-- snippet 1 -->

<style>
.red { color: red; }
.blue { color: blue; }
</style>

<!-- snippet 2 -->

<body>
<button class="blue red">Hello</button>
</body>

The color of the button is blue! Because the “blue” rule was DECLARED AFTER the “red” rule.

Besides being highly counter-intuitive and a huge gotcha for many beginners, this way of deciding which rule should prevail, LACKS FLEXIBILITY and SETS A HEAVY BURDEN on the developer shoulders. He must be extremely careful when writing CSS rules.

Technically, this subject is called CSS Precedence Rules.

And, as if the current issue was not enough, we have more issues with the precedence rules of CSS. We will see this on the next section.

The irony is that CSS was meant to be a simple, declarative language!

The second issue with the CSS Precedence Rules

What we have seen in the previous section is NOT the main (primary) precedence rule of CSS. It appeared first in the article because it is, by far, the first source of trouble.

The primary precedence criterion is this, by the highest precedence:

  1. inline style
  2. specific element (ID)
  3. classes, pseudo-classes and attributes
  4. tag
<!-- snippet 1 -->

<style>
#my-button { color: red; }
.blue { color: blue; }
</style>

<!-- snippet 2 -->

<body>
<button id="my-button" class="blue">Hello</button>
</body>

This time, the color of the button is red. Although the “blue” rule was declared after the rule for the HTML element, this has no relevance because the primary criterion for precedence is being applied: a declaration for an individual element is superior to a declaration for a class.

Maybe you are thinking, “What is the problem now?”.

For the starters, allowing to declare style on those four different levels is messy. And what often people do is using compound selectors:

<!-- snippet 1 -->

<style>
#technical b { color: red; }
.blue { color: blue; }
</style>


<!-- snippet 2 -->

<body>
<p id="technical">
The <b>width</b> is <b class="blue">20px</b>.
</p>
</body>

Suppose you are writing a webpage that contains a technical paragraph about CSS. And you want to show

  • name of attributes in bold red
  • value of attributes in bold blue

The code above will NOT work. Against our intuition, everything bold in that paragraph will be red.

Although we are applying the color red to the tag “b” that has the lowest level of precedence, we are doing it through a compound selector that starts with the Id “technical”, having the second-highest level of precedence.

There is NO such thing as class declaration in CSS!!!

"use strict"

var color = "white"

function changeColor() {
color = "red"
}

Look at the code above. There is one line where a global variable is declared (and assigned). There is a GROUP of (continuous) lines where a function is declared. You will never find parts of that function spread everywhere, even less in another file.

Now, when it comes to the CSS style sheets, what we have is CSS syntax for writing rules:

Image from studentweb.elgin.edu

“declaration” has a different meaning in CSS.

If we are looking for a traditional declaration like in (the other) programming languages, the best we can find is a (often very fragmented) pseudo declaration, where a class is born magically from many places (even files) at the same time.

/* file general.css */
.my-class { font-family: Arial; }
.my-class, .my-other-class { width: 50%; }
@media only screen and (max-width: 320px) {
.my-class {
display: none;
}
}


/* file products.css */
#products .my-class { color: green; }

/* file clients.css */
#clients .my-class { color: red; }

The code above matches the preference of some developers. They say it is good because changing the font family in just one place have automatic effects everywhere. This is true - for good and FOR BAD.

What a messy puzzle!

All we have seen are extremely simple cases. Now, think of a big website with hundreds of CSS rules, some applied to tags, others to classes, others to ids, using compound selectors, think on the problem of precedence by the position where the rules are written… what a mess!

Every time you edit part of the CSS, you are risking breaking another part!

No wonder the abundance of JavaScript frameworks and CSS preprocessors!

The Tailwind approach

The Great Heretic of the house of Tailwind looked at that mess and said, “I will never suffer this way again. If writing CSS is the root of all evil, I will no longer write CSS in my life.” — like a true romantic rebel hero would say.

And Tailwind successfully solved the CSS mess by letting the developer only writing atomic classes in each HTML element tag.

Atomic classes don’t clash, because they are too much specific, they complement themselves. Therefore, you can say goodbye to the issues with precedence rules. In fact, you had already said goodbye, because you are not writing CSS anymore — Tailwind writes the CSS code for you.

Also, we don’t need to read the whole CSS code trying to figure out how it works. We just read and edit the presentational classes inside the tag of the HTML element that we are interested in.

The downsides:

  • heavy, bloated HTML files
  • hard to read and hard to maintain(*) code (although we don’t touch CSS anymore)
  • we need to study Tailwind
  • more code to write

(*) In case all we need is editing the CSS attribute of a specific HTML element, it is not hard, it is easy.

The Zen Garden approach

And what the temple guardians at Zen Garden said?

They said, “Life is hard, but our faith is strong. We will not allow the evil seduction to deviate us!”.

They kept loyal to the Separation of Concerns and have being using the antique, secret knowledge of Alchemy to perform their CSS duties.

There are rumors that some of the priests left the fraternity, and regressed after a few years, with deep regret in their hearts.

Recently, I had separate contacts with two high priests. Both offered me similar solutions for styling two groups of buttons (say, “primary” and “secondary”). This was the most refined solution:

button {
border: 1px solid #000;
border-radius: 4px;
}
button.primary {
color: #fff;
font-weight: bold;
background: #ffa500;
}
button:not(.primary) {
color: #000;
background: #808080;
}

This solution applies CSS to the following selectors

  • tag (“button”)
  • compound selector tag — class(“button.class”)
  • compound selector tag —pseudo class(“button:not(.primary)”)

No one can deny that is pretty sophisticated. But I feel it is too much Alchemy for a very simple task.

If a third kind of button is introduced, “button:not(.primary) becomes a problem. Now, imagine this sophistication spread in hundreds of CSS rules of a big website…

We will see a simpler solution in the next section.

But I have to admire the abnegation of those high priests: they despise simple, mundane solutions, choosing something that resembles better their spiritual illumination.

The Molecular CSS approach

The Molecular CSS approach is all about simplicity, uniformity and pragmatism.

.primary {
border: 1px solid #000;
border-radius: 4px;
color: #fff;
font-weight: bold;
background: #ffa500;
}
.secondary {
border: 1px solid #000;
border-radius: 4px;
color: #000;
background: #808080;
}

Above we see the most possibly simple, readable, reusable, and maintainable CSS code for that task — we can fully change the style of one group of buttons without affect the other. Also, the code is short.

It feels like we are assigning objects to variables in JavaScript!

Just two rules, using simple class selectors. All about the “primary” class in one place only. The same goes for the “secondary” class.

We can copy each rule independently and paste it somewhere else. Very reusable. We can apply “primary” or “secondary” to any tag in the HTML code that we want! — need not be a button.

Maybe some high priest would complain that the same two lines of code appear in both rules (classes):

border: 1px solid #000;
border-radius: 4px;

And I would answer: “Is that a problem? Don’t come with dogmas!”.

Let’s be objective.

Both codes have exactly the same number of lines: 13.

Let’s count the number of visible characters (less is better):

  • high priest: 161
  • Molecular CSS: 175 (14 characters longer, not an issue)

Let’s check the HTML code:

<!-- high priest -->
<button class="primary"></button>
<button></button>

<!-- Molecular CSS -->
<button class="primary"></button>
<button class="secondary"></button>

The high priest’s HTML code can be shorter because it uses the pseudo class “button:not(.primary)”. And I ask, is that a benefit?

What do we think when we read the high priest’s HTML code? We think that no style was applied to the second button! That’s what I am talking about: Alchemy is dangerous.

Molecular CSS — the first principle

Since one of the problems with the CSS rules is that there are too many ways to write it, Molecular CSS chose just one way and banished all the others.

The banished ones:

  • in line CSS (<button style=”…”>)
  • id selectors (#id { … } )
  • tag selectors (button {…}) — except for the universal reset style sheet
  • compound selectors (.my-class1 .my-class2 {…}) — no comma

WE ONLY USE (single) CLASS SELECTORS (.my-class {…}).

Just doing this means avoiding half of the mess.

This principle alone guarantees one of the main advantages of Tailwind: just reading the classes written in the tag of an element (HTML code) tell us about any style that is applied to it.

We DON’T HAVE TO scan all the style sheets, searching for all possible combinations of rules that might affect our HTML element.

Molecular CSS — the second principle

And how do we avoid the problems of Tailwind?

We don’t do atomic.

We do molecular.

A molecule is an entity that may hold many atoms *TOGETHER*.

We have seen two perfect examples of CSS molecules: the “primary” class and the “secondary” class.

Creating a CSS molecule looks like declaring a variable and assigning an object to it in JavaScript.

In case of media queries, sometimes the same class appears as selector in more than one rule. This is treated as an acceptable exception, if it cannot be avoided.

Molecular CSS — the third principle

Returning to styling buttons, what if we had a very rich styling for the “primary” button class, including rules for all situations (“active”, “hover”, “focus”, “disabled”), taking around 50 lines of CSS code?

In this case, for the secondary button, it would be cumbersome to repeat those 50 lines, modifying only a few.

We could try using “primary” as a base class and writing the “secondary” class only with attributes that differ:

<style>
.primary { /* many rules here */ }
.secondary { /* a few rules here */ }
</style>

<body>
<button class="primary"></button>
<button class="primary secondary"></button>
</body>

It works but doesn’t seem coherent. The second button should be secondary only; not primary and secondary. Let’s refactor:

<style>
.base { /* many rules here */ }
.primary { /* a few rules here */ }
.secondary { /* a few rules here */ }
</style>

<body>
<button class="base primary"></button>
<button class="base secondary"></button>
</body>

Now it is OK!

The “base” molecule holds all declarations that are common to the primary and secondary buttons.

And the “primary” and “secondary” molecules hold only the necessary complementary declarations.

As we don’t have clash of declarations — just complementing — we don’t need to think about layering the molecules.

And how do we proceed in case of clash of declarations? For example, “base” molecule says “width is 100px” and “secondary” molecule says “width is 200px”?

Considering the code above we don’t need to do anything, the “secondary” molecule naturally overrides the “base” molecule. As both draw at the first criterion of CSS precedence, the second criterion is applied: who appears later in the style sheet wins.

WE ORGANIZE THE MOLECULES IN IMAGINARY LAYERS, considering who overrides and who will be overridden.

Inside the same layer, no molecule overrides the other. Any molecule can only override a molecule of a previous layer.

In practice, we only need a few layers, from top to bottom:

  1. the reset template (only for tags)
  2. basic molecules
  3. specialized molecules
  4. (eventual layer) super specialized molecules

Summarizing Molecular CSS: philosophy, principles, result

PHILOSOPHY

  • simplicity
  • uniformity
  • pragmatism

PRINCIPLES

  • only class based CSS — NO compound selectors
  • only molecular rule/class — a class is “declared” in one place only (like a variable in all other programming languages), as much as possible
  • organization of the CSS molecules in imaginary layers, where the molecules of any layer are ready to be harmonically overridden ONLY by the molecules of *POSTERIOR* layers

RESULT

  • short, very simple, very readable, VERY maintainable, fast to write code
  • fast, always good-looking, accessibility friendly webpage

Note: Molecular CSS doesn’t guarantee that the HTML/CSS code will be the shortest possible code. It guarantees that it will be short enough, comfortably short.

The replica

Getting back to the real code subject, to make things interesting, since we are on Medium, I will create a static replica of an imaginary Medium article webpage.

Because I don’t want to break copyrights, instead of “Medium” I will have to use something like “Sodium” or “Radium”. I will have to change the logo too.

You will not be able to write replies in the replica because the experiment is not about JavaScript. Also, using contenteditable=”true” would be a mere deviation from what matters now.

I had planned to show and explain here the source code of the replica, but this article became longer than it was supposed to be.

I will write a continuation article exclusively about the replica (I will post the link at the end of the current article).

I CHALLENGE you, Children Of The Zen Garden,

to make a better replica than that!

In case any High Priest accepts the challenge, I will write here links to his/her article and replica.

EDIT: I will write those links in the next article(s) of the series.

I am not challenging the Heretics, because we live by the same side of the Force. However, you, heretic, will be very welcome to honour your House and prove your value in the battlefields.

Winter is coming…

Web As You Wish

I will take the opportunity to let you know that I’ve just released the teaser of Web As You Wish — the free online website builder I am working on.

The teaser lets you play some features.

You find the teaser here.

And below is a video of the teaser in action.

The Continuation

Here you can find the continuation of the article.

By the way, “Children Of The Zen Garden” sounds a lot like a damn cult, right? I loved that ;)

More content at PlainEnglish.io.

Sign up for our free weekly newsletter. Follow us on Twitter, LinkedIn, YouTube, and Discord.

Interested in scaling your software startup? Check out Circuit.

--

--