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

You can define some global styles for specific selector:

app.module.css
:global(.layout) {
display: flex;
}

Or define a global block:

app.module.css
:global {
.layout {
display: flex;
}
}

Then just import this file in application:

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

Typings

For prevent typescript issues with import .css files, update your custom types declaration:

typings.d.ts
declare module '*.css' {
interface IClassNames {
[className: string]: string;
}

const classNames: IClassNames;

export = classNames;
}

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": {
"commands": {
"build": {
"configurations": {
"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,
}),
],
};

External 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.

Provider

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: 'antd/dist/antd.css',
},
}),
],
});

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';

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.