CSS Architecture for Multiple Websites

CSS Architecture — Part 3

Elad Shechter
Jul 1, 2019 · 7 min read

Complex CSS architecture is not something you learn in any formal institution.

My fourth job in the web industry was as a CSS/HTML expert, in one of the leading media news companies in my country, and my primary mission was to write reusable and scalable CSS for multiple websites.

Image for post
Image for post

In this post, I will share with you the knowledge and experience I gained in this field of constructing a multiple website architecture.

Side note: nowadays, a proper project uses a CSS preprocessor. In this post, I will be using the SASS preprocessor.

This post is the third in a series of articles I’m writing about CSS architecture. To understand this post better, I recommend that you read at least the second post in this series, “CSS Architecture — Folders & Files Structure”.

Layers World

Starting a large-scale project requires thinking globally and defining what things the sites have in common. It begins with little things, like normalize, mixins, shared icons, and the partials layer (elements, components, sequences, entities, pages, and more).

For the projects (sites) to work correctly, you have to decide which styles appear in enough of the sites to warrant defining them in the base layer, and which styles aren’t, and therefore should be defined in the specific project in which they appear. It’s a practice you will achieve by trial and error. It often happens that you move styles from layer to layer when your perspective changes, until you get them balanced in a way that suits you.

After understanding this principle, you can begin making the underlying global layer. This global layer will be the starting point for all the projects (sites).

Here’s an example of a diagram that demonstrates the requirements of the company I worked for at that time.

Image for post
Image for post
Layer Structures

The base layer should be thin, only containing CSS resets, base SASS mixins, shared icons, general font (if needed), utility classes, and maybe shared grids if it suits all projects. For the _partials.scss layer (elements, components, etc.), you will mostly use the _elements.scss layer which has partials like common-popup, common forms, and common titles. You only add styles that are shared by all, or most, of the lower layers. (More about Folders & Files Structure is detailed in my previous post)

How to Structure the Layers

In our architecture, each layer has at least three files; 2 private files (local and config; I call them private because they don’t get compiled into a CSS file) and one public file (the primary layer file). The layer’s configuration file, _config.scss usually contains variables. The _local.scss file includes the content styles and acts as a kind of controller or a package manager for the layer. The third file calls those first two files (layer-name.scss).

layer-name.scss file:

@import "config";
@import "local";

Another principle that we should set for ourselves is to try and divide everything into the smallest parts (small files) possible. This principle will become very handy when you get to refactoring.

In every layer, compile only the layer-name.scss file. You should do this even in layers representing a ‘Virtual Project’ like the ‘Base Layer Framework’ in the above diagram.

For the private files, which aren’t compiled to a separate CSS file, we use an underscore (“_”) as a prefix in all file names. The underscore symbols a file which can’t stand on its own.

Notice: When importing private files, you can write their names without the underscore prefix.

Example of layer structure:

Image for post
Image for post
The _local.scss file includes all *.scss files in the local folder, which, in turn, calls all *.scss files in the private folders. The _config.scss file calls all files in the config folders.

How it looks in the folders

|- base-layer/
|- config/
|- local/
|- _config.scss
|- _local.scss
|- base-layer.css (compiled layer style)
|- base-layer.scss


Imagine we want to create a project from the base layer. We will have to build a parallel folder with the project’s name. In the following example, we’ll call it inherited-project.

Note: Locate all layers and projects in the SASS root folder.

The project has at least one _config.scss file, one _local.scss file, and the layer’s central sass file named, in our example, inherited-project.scss.

All layers/projects sit in the root folder of SASS.

|- base-layer
| |- config/
| |- local/
| |- _config.scss
| |- _local.scss
| |- base-layer.css (compiled layer style)
| |- base-layer.scss
|- inherited-project
|- config/
|- local/
|- _config.scss
|- _local.scss
|- inherited-project.css (compiled layer style)
|- inherited-project.scss

The inherited-project’s config file imports the base-layer’s config file. This way, we can add new variables, or override existing ones from the layer above (base-layer).

Here’s an example of the- inherited-project/_config.scss:

/*load base-layer configuration */
@import "../base-layer/config.scss";
/** local Config layer (add or override variables if needed)**/
@import "config/directions.scss";

The same goes for the inherited-project/_local.scss content files of the layer.

/* import base-layer local components  */
@import "../base-layer/local.scss";
/* local font */
@import "local/font-almoni.scss";
/* local components*/
@import "local/elements.scss";
@import "local/components.scss";

Inheriting from the base-project folder is the right way to build a new layer that has its unique style, based on the inheritance from the base layer.

This layer will create one CSS file, called inherited-project.css.

Override variable in inner layer

It’s straightforward to override variables using the ‘layers’ method.

Let’s say we have a variable named $base-color in the base layer and its value is blue ($base-color: blue;). Overriding this variable requires updating its value in the local _config.scss. Now all the components that use this variable — whether inherited from the base layer or defined in the local layer — will be updated with the value of the overridden color.

Global Story

Some partials aren’t used in all layers, and therefore if you define them in the base layer, the other projects will import unnecessary code. To solve this problem, I implemented another idea of global partials concept.

This concept is that partials which are used only in some layers will be placed in another new root folder (_partials) outside of any layer. Then, any layer that needs these partials can import them from the _partials global folder.

This diagram illustrates an example of separated partials:

Image for post
Image for post

Every layer can call a single partial or multiple ones from the global _partials folder, as needed.

Example of a global _partials folder:

|- _partials/
|- base-layer/
|- inherited-project/

local.scss file view of — import global partial:

/* import base-layer local components */
@import "../base-layer/local.scss";
/*local components*/
@import "local/partials.scss";
/* add global partial */
@import "../_partials/last-connection";

Few extra guidelines

  • Be well organized. Always organize your projects and maintain the best structure in a way that fits your needs.
  • Don’t repeat yourself. You can import other layers’ components by simply @importing them directly. For example, let’s say some components are defined in the ‘sports’ project, and they’re relevant to the ‘news’ site of another project. We can @import those components to the ‘news’ site. (site = layer = project)
  • Utilize IDE shortcuts. Use a code editor that enables easy refactoring without causing errors or bugs.
  • Make sure you don’t break anything while you work. Compile all root SASS files while working and continuously refactor the code to see that nothing breaks.

To Summarize

In this post, I showed my CSS Architecture approach for a multiple-websites architecture, based on the knowledge and experience I’ve gained over the years.

This post is the third in a new series of articles on CSS Architecture I have written, and I will share with you every few weeks.

If it is interesting you , you are welcome to follow me on twitter or medium.

My CSS Architecture Series:

  1. Normalize CSS or CSS Reset?!
  2. CSS Architecture — Folders & Files Structure
  3. CSS Architecture for Multiple Websites
  4. Naming Things in CSS

Final Words

That’s all;
I hope you’ve enjoyed this article and learned from my experience.
If you like this post, I would appreciate applause and sharing :-)

More of my CSS posts:
New CSS Logical Properties!
CSS Position Sticky — How It Really Works!

Who Am I?
I am Elad Shechter, a Web Developer specializing in CSS & HTML design and architecture. I work at Investing.com.

You can contact or follow me:
My Twitter

Image for post
Image for post

You Can find me in my Facebook groups:
CSS Masters
CSS Masters Israel

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store