CSS Architecture for Multiple Websites - Elad Shechter

By Elad Shechter

CSS Architecture for Multiple Websites

CSS Architecture — Part 3

Elad Shechter

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.

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

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.

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

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:

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

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

|- base-layer.scss

Inheritance

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.

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

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

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:

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

Example of a global _partials folder:

sass/ |

|- _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

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:

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
Facebook
LinkedIn

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