Search


Search something to see results

CSS Modules

CSS module is a feature that allows you to use CSS classes in a way that is safe from conflicts with other classes in the same project. To enable CSS module support, pass the module option to the parse() or transform() function. For a detailed explanation of the module options, see the module options section.


parse(css, {module: boolean | ModuleCaseTransformEnum | ModuleScopeEnumOptions | ModuleOptions});
transform(css, {module: boolean | ModuleCaseTransformEnum | ModuleScopeEnumOptions | ModuleOptions});

parseFile(css, {module: boolean | ModuleCaseTransformEnum | ModuleScopeEnumOptions | ModuleOptions});
transformFile(css, {module: boolean | ModuleCaseTransformEnum | ModuleScopeEnumOptions | ModuleOptions});

The scoped option is used to configure the scope of the generated class names.

This is the default scope.


import {transform, TransformOptions} from "@tbela99/css-parser";
import type {TransformResult} from "@tbela99/css-parser";

const css = `
.className {
background: red;
color: yellow;
}

.subClass {
composes: className;
background: blue;
}
`;

let result: TransformResult = await transform(css, {

beautify: true,
module: {scoped: ModuleScopeEnumOptions.Local
}
});

console.log(result.code);

Output:

.className_vjnt1 {
background: red;
color: #ff0
}
.subClass_sgkqy {
background: blue
}

The class names are not scoped unless they are scoped using :local or :local()


result = await transform(css, {

beautify: true,
module: {scoped: ModuleScopeEnumOptions.Global
}

});

console.log(result.code);

Output:

.className {
background: red;
color: #ff0
}
.subClass {
background: blue
}

Export CSS using ICSS format


result = await transform(css, {

beautify: true,
module: {scoped: ModuleScopeEnumOptions.ICSS
}

});

console.log(result.code);

Output:

:export {
className: className_vjnt1;
subClass: subClass_sgkqy className_vjnt1;
}
.className_vjnt1 {
background: red;
color: #ff0
}
.subClass_sgkqy {
background: blue
}

Require the use at least one id or class in selectors. It will throw an error it there are no id or class name in the selector.


result = await transform(css, {

beautify: true,
module: {scoped: ModuleScopeEnumOptions.Pure
}

});

console.log(result.code);

Output:

.className {
background: red;
color: #ff0
}
.subClass {
background: blue
}

Produce short scope names.


result = await transform(css, {

beautify: true,
module: {scoped: ModuleScopeEnumOptions.Shortest
}

});

console.log(result.code);

Output:

.a {
background: red;
color: #ff0
}
.b {
background: blue
}

Scopes can be mixed using the bitwise OR operator '|'


result = await transform(css, {

beautify: true,
module: {scoped: ModuleScopeEnumOptions.Pure | ModuleScopeEnumOptions.Global | ModuleScopeEnumOptions.ICSS
}

});

console.log(result.code);

Class composition is supported using the composes property.


import {transform, TransformOptions} from "@tbela99/css-parser";

const options: TransformOptions = {

module: true,
beautify: true,
};

const result = await transform(`
.goal .bg-indigo {
background: indigo;
}

.indigo-white {
composes: bg-indigo title;
color: white;
}
`, options);

console.log(result.code);
console.log(result.mapping);

Generated css code:

.goal_r7bhp .bg-indigo_gy28g {
background: indigo
}
.indigo-white_wims0 {
color: #fff
}

Generated class mapping:


{
"goal": "goal_r7bhp",
"bg-indigo": "bg-indigo_gy28g",
"indigo-white": "indigo-white_wims0 bg-indigo_gy28g title_qw06e",
"title": "title_qw06e"
}

Classes can be composed from other files as well as the global scope


import {transform, TransformOptions} from "@tbela99/css-parser";

const options: TransformOptions = {

module: true,
beautify: true,
};

const result = await transform(`
.goal .bg-indigo {
background: indigo;
}

.indigo-white {
composes: bg-indigo;
composes: title block ruler from global;
composes: bg-indigo title from './other-file.css';
color: white;
}
`, options);

The naming option is used to configure the case of the generated class names as well as the class mapping.

No case transformation


import {transform, ModuleCaseTransformEnum} from '@tbela99/css-parser';
import type {TransformResult} from '@tbela99/css-parser';

let css = `

:local(.class-name) {
background: red;
color: yellow;
}

:local(.sub-class) {
composes: class-name;
background: blue;
`;

let result = await transform(css, {

module: {
naming: ModuleCaseTransformEnum.IgnoreCase
}

});

console.log(result.code);

Use camel case for the mapping key names


import {transform, ModuleCaseTransformEnum} from '@tbela99/css-parser';
import type {TransformResult} from '@tbela99/css-parser';

let css = `

:local(.class-name) {
background: red;
color: yellow;
}

:local(.sub-class) {
composes: class-name;
background: blue;
`;

let result = await transform(css, {

module: {
naming: ModuleCaseTransformEnum.CamelCaseOnly
}

});

console.log(result.code);

Generated css:

.class-name_agkqy {
background: red;
color: #ff0
}
.sub-class_nfjpx {
background: blue
}

Generated mapping:

console.log(result.mapping);
{
"className": "class-name_agkqy",
"subClass": "sub-class_nfjpx"
}

Use camel case key names and the scoped class names.


import {transform, ModuleCaseTransformEnum} from '@tbela99/css-parser';
import type {TransformResult} from '@tbela99/css-parser';

let css = `

:local(.class-name) {
background: red;
color: yellow;
}

:local(.sub-class) {
composes: class-name;
background: blue;
`;

let result = await transform(css, {

module: {
naming: ModuleCaseTransformEnum.CamelCaseOnly
}

});

console.log(result.code);

Generated css:

.className_agkqy {
background: red;
color: #ff0
}
.subClass_nfjpx {
background: blue
}

Generated mapping:

console.log(result.mapping);
{
"className": "className_agkqy",
"subClass": "subClass_nfjpx"
}

Use dash case for the mapping key names


import {transform, ModuleCaseTransformEnum} from '@tbela99/css-parser';
import type {TransformResult} from '@tbela99/css-parser';

let css = `

:local(.className) {
background: red;
color: yellow;
}

:local(.subClass) {
composes: className;
background: blue;
}
`;

let result = await transform(css, {

module: {
naming: ModuleCaseTransformEnum.DashCase
}

});

console.log(result.code);

Generated css:

.className_vjnt1 {
background: red;
color: #ff0
}
.subClass_sgkqy {
background: blue
}

Generated mapping:

console.log(result.mapping);
{
"class-name": "className_vjnt1",
"sub-class": "subClass_sgkqy className_vjnt1"
}

Use dash case key names and the scoped class names.


import {transform, ModuleCaseTransformEnum} from '@tbela99/css-parser';
import type {TransformResult} from '@tbela99/css-parser';

let css = `

:local(.className) {
background: red;
color: yellow;
}

:local(.subClass) {
composes: className;
background: blue;
}
`;

let result = await transform(css, {

module: {
naming: ModuleCaseTransformEnum.DashCaseOnly
}

});

console.log(result.code);

Generated css:

.class-name_vjnt1 {
background: red;
color: #ff0
}
.sub-class_sgkqy {
background: blue
}

Generated mapping:

console.log(result.mapping);
{
"class-name": "class-name_vjnt1",
"sub-class": "sub-class_sgkqy class-name_vjnt1"
}

The pattern option is used to configure the generated scoped names.


import {transform, ModulePatternEnum} from '@tbela99/css-parser';
import type {TransformResult} from '@tbela99/css-parser';

const css = `
.className {
background: red;
color: yellow;
}

.subClass {
composes: className;
background: blue;
}
`;

let result: TransformResult = await transform(css, {

beautify: true,
module: {
pattern: '[local]-[hash:sha256]'
}

});

console.log(result.code);

Generated css:

.className-b629f {
background: red;
color: #ff0
}
.subClass-a0c35 {
background: blue
}

Generated mapping:

console.log(result.mapping);
{
"className": "className-b629f",
"subClass": "subClass-a0c35 className-b629f"
}

The supported placeholders are:

  • name: the file base name without the extension
  • hash: the file path hash
  • local: the local name
  • path: the file path
  • folder: the folder name
  • ext: the file extension

The pattern placeholders can optionally have a maximum number of characters:

pattern: '[local:2]-[hash:5]'

The hash pattern can take an algorithm, a maximum number of characters or both:

pattern: '[local]-[hash:base64:5]'

or

pattern: '[local]-[hash:5]'

or

pattern: '[local]-[hash:sha1]'

Supported hash algorithms are:

  • base64
  • hex
  • base64url
  • sha1
  • sha256
  • sha384
  • sha512

← Validation | Minification →