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
- Button.module.css
import styles from './Button.module.css';
export const Button = () => <button className={styles.button} />;
.button {
cursor: pointer;
}
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:
/// <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
:
{
"projects": {
"appName": {
"postcss": {
"config": "src/postcss"
}
}
}
}
Recommended list of plugins are already included for new tramvai
applications, and default configuration looks like this:
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
- Yarn
npm install --save-dev postcss-global-import
yarn add --dev postcss-global-import
⌛ Add plugin to application:
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:
@global-import "antd/dist/antd.css";
⌛ And last, import this CSS module in the application:
import './antd.module.css';
External import
With multi token RENDER_SLOTS
you can easily add external styles to every application page:
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.