Component CSS naming conventions
The BEM naming convention for CSS is widely used and has been around for a long time. But it is pre web component and there are several new CSS naming conventions to fit in with web components.
The Block is now the Component
The B in BEM stands for block because each HTML statement is said to create a block in the viewport. The block name identifies what is in the block like mainmenu, sidebar, infomodal etc.
The BEM naming convention would have us create a css class=”pageloading”. All lower case. By convention names were restricted to lower case to avoid case errors. Pageloading is not the same as PageLoading.
Component based CSS naming conventions like SUIT as described here SUIT CSS: style tools for UI components calls for each component to have a css class name that is the same as the component. These class names have upper case letters. This class serves the same function as the class for each HTML CSS class.
When an HTML statement is rendered, it first inherits style properties from the parent and then has styles set by the user agent. As you can see the color and background color properties are assigned values by the user agent for the dialog statement but not for the div. That is why the div in PageLoading inherited the blue background and dialog did not.
Create a PageLoading class in the app.css file and set the style properties to have colors and borders like the dialog. Change the dialog class so the background is yellow. Now whenever a dialog appears on any page the background will be yellow.
The Element is now the Part
But we may only want the dialog to be yellow when it is inside the PageLoading component. This is the E in BEM as we are creating a class for an element inside the block. We create a class that sets the dialog yellow when it is inside the PageLoading. BEM would have
BEM: pageloading__dialog
SUIT: PageLoading-dialog.
So we remove the dialog color setting and create a new class in the css file to set the colors for PageLoading-dialog class.
Suit calls this a component part that could be an element or another component. The component class name and the component part class names are only found on statements inside the component. They should never be used inside other components.
In Blazor we can set style properties in the app.css file and in the components razor.css file. Properties set in razor.css are locked. The locked properties can be modified by C# code but not by the external css file. Nonvisual properties should be locked and protected from modification. Only the visual theming properties should be in the external css. The locked properties are also safe from CSS class name collisions.
Modifier is still modifier
The M in BEM stands for modifier. The purpose of a modifier class is to alter some style properties. The base class (PageLoading) will define the default style settings for the web object. A modifier will modify the style settings for a component for some specific purpose such as theming. We may want the dialog in PageLoading to have different colors on different pages. In BEM and SUIT the separator for a modifier is the same, double dash --.
BEM: pageloading--modifier
SUIT: PageLoading--modifier
The modifier class name is passed to the component as a parameter from the parent component. The component then has to add the modifier class name to the proper HTML statements inside the component.
So, we create a class named PageLoading-dialog—GreenDialog, the parent component contains:
<PageLoading Class=”PageLoading-dialog—GreenDialog”>
The PageLoading component would know that the class name passed to it is a modifier because it has a double dash. The text before the — is the key to locate which statements the modifier class name should be added to. So
<dialog class=”PageLoading-dialog”>
inside of PageLoading would become
<dialog class=”PageLoading-dialog PageLoading-dialog—GreenDialog”>
But what if we have a CSS class named fancy_dialog that we want to use in PageLoading and in other components. The parent component would contain:
<PageLoading Class=”PageLoading-dialog.fancy-dialog”>
We would pass the class name PageLoading-dialog.fancy-dialog to the component and it will only add fancy-dialog to the class names.
<dialog class=”PageLoading-dialog”>
inside of PageLoading it would become_
<dialog class=”PageLoading-dialog fancy-dialog”>
The fancy-dialog class name is all lower case because it is not associated with a component.
Implementation
The base Blazor component class does not have any parameters defined. To implement this naming convention, we must define the parameters and add code. That is what we will cover in the next lesson.
One way to code for the mediator class is to create two parameters one named Class for setting values on the div and one named Class-dialog for setting values on the dialog statement.
The other option is to have just one Class parameter and use the name that is on the left of the — as a key to determine where to add the modifier.
Recommendations:
For every component create a CSS class with the same name.
The component should contain an outer container such as div that has the component class name.
Set the default and locked style properties for your component in the css file and the razor.css file.
To override the unlocked component values, create a part or mediator css class.