Skip to main content

Styling

CSS Modules​

tramvai provides CSS Modules as default approach for styling. Any imports of CSS files as JS modules will be processed as CSS Modules, for example if we try to create a Button component:

Button.tsx
import styles from './Button.module.css';

export const Button = () => <button className={styles.button} />;
tip

It is not required at this moment, but prefer use .module.css suffix for CSS files - in a future releases only filenames with this pattern will be processed as CSS Modules

Global styles​

All *.css file imports will be treated as CSS Modules by default. To disable CSS Modules processing for specific styles within a CSS file, you can use the :global scope. For example:

.header {
background-color: red;
}

:global .global-header {
background-color: blue;
}

In this example, the .header class will be processed as a CSS Module, while the .global-header class will not be processed as a module and will have a global scope.

To disable CSS Modules processing for specific files, such as global styles, you can add the cssModulePattern regular expression to the configuration as follows:

{
"postcss": {
// CSS Modules processing will be skipped for *.global.css files
"cssModulePattern": "^(?!.*global\\.css$).*$"
}
}

Typings​

For prevent typescript issues with import .css files, make sure that your custom types declaration contains @tramvai/cli package reference:

typings.d.ts
/// <reference types="@tramvai/cli" />

PostCSS​

tramvai provides complete PostCSS integration. Default path for file with PostCSS plugins is postcss.config.js, and is defined by the parameter postcss.config in tramvai.json:

tramvai.json
{
"projects": {
"appName": {
"postcss": {
"config": "src/postcss"
}
}
}
}

Recommended list of plugins are already included for new tramvai applications, and default configuration looks like this:

src/postcss.js
module.exports = {
plugins: [
require('postcss-nested'),
require('postcss-modules-values-replace'),
require('postcss-custom-properties')({
preserve: false,
}),
require('postcss-custom-media')({
preserve: false,
}),
],
};

Third-party styles​

For example, we want to include antd styles - antd/dist/antd.css. We have a few options for this - direct import in CSS file, or with DI provider.

Local import​

⌛ First, install postcss-global-import plugin:

npm install --save-dev postcss-global-import

⌛ Add plugin to application:

src/postcss.js
module.exports = {
plugins: [
require('postcss-nested'),
require('postcss-modules-values-replace'),
require('postcss-custom-properties')({
preserve: false,
}),
require('postcss-custom-media')({
preserve: false,
}),
require("postcss-global-import"),
],
};

⌛ Import file in any CSS module with @global-import directive:

antd.module.css
@global-import "antd/dist/antd.css";

⌛ And last, import this CSS module in the application:

index.ts
import './antd.module.css';

External import​

With multi token RENDER_SLOTS you can easily add external styles to every application page:

index.ts
import { createApp, provide } from '@tramvai/core';
import { RENDER_SLOTS, ResourceType, ResourceSlot } from '@tramvai/module-render';

createApp({
name: 'appName',
modules: [],
providers: [
provide({
provide: RENDER_SLOTS,
useValue: {
type: ResourceType.style,
slot: ResourceSlot.HEAD_CORE_STYLES,
payload: 'https://cdnjs.cloudflare.com/ajax/libs/antd/4.24.5/antd.min.css',
},
}),
],
});

Performance​

Class names​

Library @tinkoff/minicss-class-generator used underhood for creation of short and unique class names. You can configure generator pattern with cssLocalIdentName option in tramvai.json.

Resource inlining​

Any CSS files smaller than 40kb before gzip will be inlined in HTML markup. You can configure automatic resource inlining with provider RESOURCE_INLINE_OPTIONS.