Easily scope/namespace theme and block CSS using Less and Sass to prevent CSS conflicts

This is a community-contributed tutorial. This tutorial is over a year old and may not apply to your version of Concrete CMS.
Mar 31, 2017

This tutorial is an updated legacy how-to by JohntheFish.

Themes, jQuery plugins and all sorts of widgets from outside of Concrete CMS often come with CSS that interferes with other aspects of a site or the Concrete dashboard. You can easily use a Less or Sass compiler to quickly limit the scope of such CSS. Even if you have not spotted any conflicts yet, limiting the scope of CSS is generally a good design practice that can help avoid trouble in the future. Limiting the scope of CSS is actually recommended in Concrete theme and block making guidelines.

When deciding on what CSS selector to scope your theme CSS to, an easy choice is to use .ccm-page. The .ccm-page wrapper class is conveniently part of every theme because of the required getPageWrapperClass() method.

<!-- Concrete and theme header stuff -->
<body>
    <div class="<?php echo $c->getPageWrapperClass(); ?>">
        <!-- page type layout for theme -->
    </div>
    <!-- Concrete footer stuff -->
</body>

That is just background. If you look through the documentation and tutorials there is plenty more to read about structuring themes.

Suppose you already have a mass of CSS, from a theme you are importing or from a framework you are building a theme from. It may contain hundreds or thousands of styles. You don’t really want to have to go through all those styles one-by-one and prefix them with .ccm-page. It’s a tedious and error prone task that can only become a maintenance nightmare.

The trick is to use Less or Sass to add scope. Less and Sass are extensions to CSS that, when processed by a respective compiler, output pure CSS. Take all the CSS you want to scope, wrap it in a single scope declaration and apply the Less or Sass compiler. The output will be fully scoped CSS.

There are many ways to implement the details. If the theme is already built from Less or Sass, you can usually just create another file with the scope declaration that includes all the various component files within the scope declaration. Or you could edit the outermost file to add a line to open the scope at the top and another close it at the end. You may also need to change the extension of all the files you are compiling to end in .less or .scss so the compiler will know to process them.

Do some Googling and you will soon find Less and Sass compilers that you can run from the desktop, run online from a web site or build directly into your site to compile on demand. Starting with Concrete 5.7, a Less compiler is included with Concrete and allows you to use .less files in your theme.

Let’s begin with the trivial case of a simple style sheet for the "Monster Font" theme that inconveniently globally over-sizes all paragraphs. That may be what the theme wants, but it turns out some parts of the dashboard are also suffering monster sizing.

p {
    font-size: 50px;
}

To limit the scope you can wrap it in your scope class:

.ccm-page {
    p {
        font-size: 50px;
    }
}

When you then compile the Less or Sass, the resulting CSS will be:

.ccm-page p {
    font-size: 50px;
}

The over-sized paragraph font is now constrained to only apply to paragraphs inside .ccm-page and cannot interfere with anything outside that container.

That was just a trivial example. The technique extends to wrapping many styles in one go. What you are aiming for is an outer wrapper for all the styles that looks like:

.ccm-page {
    // wrap all styles inside here
}

You aren't limited to wrapping individual styles, you can wrap entire files using @import:

Less

.ccm-page {
    @import "grid.less";
    @import "blocks.less";
    @import "typography.less";
}

Sass

.ccm-page {
    @import "grid";
    @import "blocks";
    @import "typography";
}

After compiling, all the styles in the imported files would be scoped to .ccm-page.

The same approach for scoping theme CSS is used for scoping block CSS, the only difference is the class you use for scoping. A general recommendation for naming the block scope class is to use the class prefix of "ccm-block-" followed by the block handle. For example, if your block handle was "my_block_name", then your block scope class would be .ccm-block-my-block-name. This class would then be applied to the element that wraps your block HTML, or depending on the type of block and structure, it would be applied to parent elements in your block HTML.

When you compile the Less or Sass, the output will be CSS that is all instantly scoped to your container. Styles that argue with the dashboard, with other themes, other block templates or other jQuery widgets should be a thing of the past.

Recent Tutorials
Reusing the same Express entity in multiple associations
Apr 11, 2024
By myq.

How to create and manage multiple associations in Express

Express Form Styling
Apr 11, 2024
By myq.

Different ways to style Express forms

Setting addon/theme version compatibility in the marketplace
Jan 9, 2024

For developers worn out with setting the latest addon or theme version manually across too many core versions, here is a JavaScript bookmarklet to do it for you.

How to get the locale of a page
Jan 8, 2024
By wtfdesign.

Now, why don't we just have a getLocale() method on Page objects beats me, but here's how you work around it

Using a Redis Server
Jun 16, 2023
By mlocati.

How to configure Concrete to use one or more Redis servers to persist the cache.

Using the Concrete Migration Tool Addon
Apr 27, 2023

How to use the Concrete CMS Migration Tool

Improvements?

Let us know by posting here.