Article
4 comments

How to handle automatic CSS class renaming in SPFx

The new SharePoint Framework has a safety net when you develop and style your components. Whenever you write a new style sheet class this will be picked up by a SASS preprocessor that first compiles the SASS file and then applies a special random string to the class name.
This should theoretically avoid that two web parts have conflicting style sheet classes. If one web part uses the style sheet class ‘item’ and another web part uses the same class name. The last web part embedded on the page will win the battle how the item should look like. Through this renaming you make sure that every web part has an individual definition of the item. In general this is a good behavior.
On the other hand, you have frameworks or Office UI Fabric where those classes won’t be renamed.
There are also some negative impacts caused by that method and there is also an easy way to disable this renaming of style sheet classes. If you do so, then you need to be aware of certain things on how to make your styles available exclusively just for your web part.

Disable auto-renaming on web parts

To disable the renaming of style sheet classes simply remove the ‘module’ from the ‘.module.scss’. The style definition still will be picked up by the SASS preprocessing but the class names won’t be renamed anymore. Now the original class name can be used in the web part code and in the components rather than dealing with variables that defines the styles.
The problem now is that your style sheet classes won’t be loaded in the browser. On the Github repository I built for this article, you will find a ‘DisableAutoPrefix’ web part. In this web part I simply renamed ‘DisableAutoPrefix.module.scss’ to ‘DisableAutoPrefix.scss’.
This was only the first step in the components I removed the following line.

import styles from '../DisabledAutoPrefix.module.scss';

View on Github

To load the style sheet I added the following line directly on the web part.

require('DisabledAutoPrefix.css');

View on Github

The important thing here is that the compiled CSS file needs to be referenced and not the SASS file. Finally, I converted the variables in the component back to the original class names. That’s all that needs to be done to disable the auto renaming of the class names. Now that we disabled the safety net for our classes we need to create another one that is easier to use and more web development friendly. We need to scope our style sheets just to affect only our web part.

Scope CSS class names for your own safety

Let me show you a method how your style sheet classes will only affect the web part but not the page. We like to make sure that only our web part is affected by the class names and not the rest of the page. This is known as scoping in CSS. The following simple example mimics a web part just by using HTML and SASS. It contains a title, text content and an image. Each of those elements has their own style sheet classes. In addition, I have a surrounding container that represents the web part content container.

See the Pen Web Part Sample by Stefan Bauer (@StfBauer) on CodePen.14928

Normally you might tend to define the styles like this.

.mywebpart{
    /* Styles of my web part */
}

.headline{
    /* Styles of my headline */
}

.content{
    /* Styles of content */
}

.image{
    /* Styles of image */
}

The problem with this approach is that the class definitions are global scoped. This means that you overwrite other definitions that might use in other web parts.
With a slightly structural change, especially with SASS, all style definitions can be scoped to the web part container. Styles outside of that web part won’t be affected.

/* Global definition of web part */
.mywebpart{
    /* Styles of my web part */
    
    /* Local Style of headlines */
    .headline{
    }

    /* Local Style of content */    
    .content{
    }
    
    /* Local Style of content */    
    .image{
    }

}

Now the styles of headline, content and image will only be applied to the web part and won’t have any effect on the surrounding page.

See the Pen Web Part Sample – prefixed styles by Stefan Bauer (@StfBauer) on CodePen.14928

Works perfectly for one web part, but how to deal with multiple web parts on a page? The easiest solution is to prefix the style sheet classes. Sorry, not the classes just the style sheet class of the web part. Simplified. The first web part type has a core class of .webpart_1, second web part has .webpart_2 and so on. If the attached strings to the class names are unique and wraps your inner style sheet definitions, then you are really fail safe with your styling.
Instead of using different names for each and every class you just need to have a unique name for the surrounding class.
In SPFx you have to define the surrounding div element and the unique class name manually. You might use the same class name that was originally proposed by SPFX just for the surrounding container.
The following screenshot first shows the original web parts with the renaming enable. The second web part uses the same code, but renaming is disable. Both look the same and both accomplish the goal that style sheets will be only applied to the web part.

Auto rename enabled and disabled – Both web parts same design

Dealing with frameworks

Let’s assume you load different web parts load different versions and different frameworks on a SharePoint page. You might run into troubles. By default SPFx doesn’t prefix those external style sheet definitions. You might have web parts already built as script or content editor web parts that use Bootstrap components. In this case again the framework is scoped globally. To make it failsafe add the Bootstrap CSS to your project and use the following approach.
First, create a unique identifier container for the outer container that wraps your code. In your style sheet, then you make use of the SASS import statement directly in your unique web part class.

.mywebpart_12345{

   @import 'bootstrap';
      
   /* add your style here */
   
}

This way all style definitions of bootstrap will be prefixed with your web part container class and bootstrap will only affect the web part and not the whole page.
To demo how this works I simply created two web parts that use the same style sheet classes, but only one web part uses Bootstrap.

The first web part uses bootstrap, the second web part is not affected by bootstrap

As you see only one web part is affected. The rest of the page doesn’t even recognize those style definitions. Here again auto renaming is disabled. Otherwise, this prefixing wouldn’t work.
I will provide a more detail and explanation on an upcoming post because I think this is an essential part, when you try to migrate web parts to SPFx.
For now you can take a look at the Github samples.

Is the default renaming failsafe?

Now that I showed an alternative way to make your web part style sheets fail safe, lets do a really stupid example to show that the default renaming has some limitations.
I created two web parts. One is named ‘Pink Web Part’, the other is named ‘Black Web part’. Those web parts simply apply a background color to the page using the body tag.
In this race the last web part on the page wins. If the pink web part comes last then the background will be changed to pink.

web part changes the body background to pink

Web part changes the body background to pink

 

Changing the order of the web parts. The background will be set to black.

Web part changes the body backround to black

Web part changes the body background to black

The problem here is that default body HTML tags cannot be renamed. As told before it’s just a stupid example, but can lead to problems. In fact, you always should use CSS classes and never style an HTML tags alone.

Final thought and personal preferences

Over the last years one thing becomes really important for the web industry. Whenever you define a design or just a single component create a proper style documentation in HTML first. Those documentations are also known as style guides. This style guide should also be done apart from the actual implementation. A good example for such style guide is the Office UI Fabric that uses only HTML and CSS for the core implementation. Based on that React and Angular implementations can be done.
This also implies that the style sheet classes of all components and even the HTML templates and components will be defined outside of SharePoint or SPFx.
It is important to keep your design documentation with the actual implementation consistent. In this case this random renaming of the style sheet classes is not a good idea. Even SPFx doesn’t rename Office UI Fabric classes which might would be useful if different versions are included in the web parts.
On the other hand, you need to make sure that your implemented web parts and the used component don’t break any other component on the page.
From my perspective, I tend to disable this auto renaming rather than using it. The implementation with is less time consuming and I have a proper relationship between style guide and implementation.
The only thing that I need to make sure is that the surrounding div use a unique class name and add my styles are defined beneath that class name.
My hope for the future releases of the framework is that this unique class name will be provided by the SharePoint Framework. Whenever a new web part type will be generated the surrounding unique class name will be automatically assigned.
During the SASS style sheet compilation the unique id can automatically wrap around my style definitions as we did in the Bootstrap example. This will also have the benefit that even standard HTML tag will be scoped. In a long run it will lead to much cleaner code.
Sooner or later that same scoping will come anyway to SharePoint through web components or frameworks.
Finally, let me know what you think about the show approaches here?

4 Comments

  1. This is a nice approach if you control all the HTML/CSS on the page.

    The only problem with this solution is if some other component that you don’t control uses one of your classes and applies styling to it (e.g. a third-party widget or if your code is being included as a widget). Your styles won’t affect the third-party code, but if it is not similarly scoped, then it will mess up yours.

    In this case, you would have to rename all of your class names (including the nested ones) to include a unique prefix to avoid any conflicts.

    Reply

Leave a Reply

Required fields are marked *.


This site uses Akismet to reduce spam. Learn how your comment data is processed.