Mimcss Guide: Assigning names
Previous Unit: Custom properties Next Unit: Activation strategies

Assigning names

We already mentioned that the style definition property names you use when referring to your classes, IDs, animations, custom properties and other named rules are not the names that are actually used in HTML. The actual names are auto-generated by Mimcss, which ensures that they are unique.

Modes of assigning names

Mimcss has three modes of assigning names, which are identified by the NameGenerationMethod enumeration.

The first method is called Optimized. It creates names by appending an incrementally increasing number to a prefix. The default prefix is "n" but it can be changed programmatically. This method produces short names without a real possibility to relate back to the place in the code where they were defined; therefore, this method should be used only for production builds. This method is used by default in the production build of the Mimcss library.

The second mode is called UniqueScoped. It creates names that combine the name of the style definition class that defines the property, the name of the property itself and an incrementally increasing number. This method produces unique names that clearly refer to the place where they were defined and, therefore, this method should be used during development. This method ensures that even if there are two identically named classes (in different JavaScript modules) that have a property with the same name, the generated name will still be unique.

The third mode is called Scoped. It creates names that combine the name of the style definition class that defines the property and the name of the property itself. As there are no unique numbers involved, this method produces predictable names and, therefore, can be used during testing that utilizes tools relying on artifacts such as CSS class and element identifier names. Note that under rare conditions (e.g. if two identically named classes define properties with identical names), this method can produce non-unique CSS names; therefore, this method is recommended only for limited and specific testing. This method is used by default in the development build of the Mimcss library.

Applications can call the Mimcss configNameGeneration function to switch to a desired method. This function accepts an optional prefix parameter that can specify the prefix to be used when generating unique names. Note that the configNameGeneration function must be called very early in the application life because the mode must be set before any style definition classes are processed.

Name scoping

Different style definition classes can define properties with identical names and they will be unique when applied to HTML. We call it name scoping, which means that names are scoped to the style definition classes.

Consider the following example, where we have two classes (that might be coming from different libraries):

/* MyStyles.ts */
export class MyStyles extends css.StyleDefinition
{
    emphasized = this.$class({ color: "red", fontWeight: 700 });
});

/* OtherStyles.ts */
export class OtherStyles extends css.StyleDefinition
{
    emphasized = this.$class({ color: "orange", fontStyle: "italic" });
});

/* MyComponent.tsx */
import {MyStyles} from "./MyStyles"
import {OtherStyles} from "./OtherStyles"

let myStyles = css.activate(MyStyles);
let otherStyles = css.activate(OtherStyles);

render()
{
    return <div>
        <p className={myStyles.emphasized.name}>Hello!</p>
        <p className={otherStyles.emphasized.name}>Hello!</p>
    </div>

Although the names of the properties defining the CSS classes are the same, Mimcss will use different names when creating CSS rules and inserting them into the DOM.

Under the UniqueScoped mode, the string value of the myStyles.emphasized.name property might be ".MyStyles_3_emphasized_25", while the string value of the otherStyles.emphasized.name property might be ".OtherStyles_7_emphasized_73". Under the Optimized mode, the names might be created as n25 and n73. This would be obviously much more difficult to debug.

Explicit names

There are situations when we need to bypass the Mimcss name auto-generation. One use case is when we want to override a class that comes from a CSS file (remember that Mimcss is not “all-or-nothing” library). In this case, we can specify the names explicitly. The functions that produce named rules - $class, $id, $var and others - accept an optional parameter where we can provide the name as a string. For example,

class MyStyles extends css.StyleDefinition
{
    box = this.$class( { margin: 8 }, "box-class-name")
}

Another use case is when we have an external style definition class and we want to use the rule name defined there for our rule. To accomplish this, we use the same optional parameter - but this time we pass the rule object to it:

// the 'LibStyles' class from the 'lib' library has a CSS class rule assigned to property 'box'
import {LibStyles} from "lib"

class MyStyles extends css.StyleDefinition
{
    lib = this.$use(LibStyles)

    box = this.$class( { margin: 8 }, this.lib.box)
}

Names in grouping rules

Conditional grouping rules such as @media, @supports and @layer posit a different problem. Names of classes defined under these grouping rules (at least some of them) are supposed to match those defined outside the conditions, so that style values defined within the grouping rules will take effect when the conditions evaluate to true. Consider the following example:

class MyStyles extends css.StyleDefinition
{
    box = this.$class( { margin: 8 })

    ifSmallScreen = this.$media( { maxWidth: 600 },
        class extends css.StyleDefinition<MyStyles>
        {
            box = this.$class({ margin: 4 })
        }
    )
}

let myStyles = css.activate(MyStyles);

render()
{
    return <div>
        <p className={myStyles.box.name}>Hello!</p>
   </div>

We have two properties named box: the first one is defined at the top level of the class definition, and the second one - inside the @media rule. The names assigned by Mimcss must be the same for both properties.

Mimcss solves this problem with a simple convention: within the same style definition class, if a rule inside a grouping rule is assigned to a property with the same name as the property at the upper level, the same actual name will be assigned to them.

In the example above, when Mimcss processes the MyStyle class the box property gets assigned a name first. When the second box property is encountered, Mimcss finds this name at the top level and assigns it to the second property too.


Previous Unit: Custom properties Next Unit: Activation strategies