Styling
Although UI Kit components are pre-styled with with the Design System specifications, sometimes there’s a need to customize them in order to meet your specific needs.
Styling properties
The UI Kit components can be customized the following ways:
style
and className
UI Kit components can be styled using the React style
and className
props, as these props are passed down to the root HTML element.
The style
prop accepts a JS object with CSS properties, while the className
prop accepts a string with CSS classes,
which allows for the use of various styling strategies.
<HvButton
style={{ marginLeft: "auto", borderColor: "red" }}
className="ml-auto border-red"
/>
classes
object
As many UI Kit components are built using multiple HTML elements and internal state, the classes
prop allows for customization of these sub-components and state variants.
The classes.root
(along with className
and style
) is passed to the main element of the component, and the conditional classes are applied to the same element.
<HvButton
classes={{
root: "p-xs", // applied to the top-level element, same as `className`
disabled: "bg-black", // applied to the `root` element, WHEN the component is disabled
startIcon: "bg-red", // applied to the start/left icon element container
}}
/>
These classes are also injected as CSS classes HTML elements, following a Hv{ComponentName}-{className}
naming convention, and are exported as a <componentName>Classes
object:
import { buttonClasses } from "@hitachivantara/uikit-react-core";
buttonClasses.root; // "HvButton-root"
buttonClasses.disabled; // "HvButton-disabled"
buttonClasses.startIcon; // "HvButton-startIcon"
Styling strategies
The className
property allows for the use of many styling strategies, such as
Global CSS, CSS Modules, Utility classes like Tailwind or UnoCSS, CSS-in-JS like Emotion, etc.
This guide will focus on UnoCSS (Utility classes) and Emotion (CSS-in-JS). For other styling strategies and tools, please refer to their respective documentation.
Emotion
The UI Kit is built using Emotion, a CSS-in-JS library that allows for the use of dynamic styles and theming.
Emotion supports creating complex, reusable classes using the css
prop, or components via the styled
function.
It is especially useful when dealing with complex styles or overrides, or when the components need additional overrides.
Please check out the Emotion Best Practices for a guide on how to use Emotion effectively, such as leveraging colocation or type-safety.
Using the css
function
import { css } from "@emotion/css";
import { buttonClasses, theme } from "@hitachivantara/uikit-react-core";
const classes = {
button: css({
backgroundColor: theme.colors.negative,
[`:hover:not(:disabled) ${buttonClasses.startIcon}`]: {
backgroundColor: theme.colors.negativeDimmed,
},
"@media (max-width: 600px)": {
backgroundColor: theme.colors.positive,
},
}),
};
<button className={classes.button} />;
Using the styled
function
import styled from "@emotion/styled";
import { buttonClasses, theme } from "@hitachivantara/uikit-react-core";
const CustomButton = styled(HvButton)({
backgroundColor: theme.colors.negative,
[`:hover:not(:disabled) ${buttonClasses.startIcon}`]: {
backgroundColor: theme.colors.negativeDimmed,
},
"@media (max-width: 600px)": {
backgroundColor: theme.colors.positive,
},
});
<CustomButton />;
UnoCSS
Utility classes, popularized by frameworks like TailwindCSS, offer a streamlined and efficient way to style components, allowing to colocate elements and styles while allowing access to theme-based values.
The UI Kit team recommends utility classes due to their built-in theme support, performance (no runtime or external dependencies), portability (to any build tool or framework), and colocation (easier maintenance).
UI Kit offers a utility classes plugin via a UnoCSS plugin, @hitachivantara/uikit-uno-preset
.
Setup
Please check out the uno-preset package and the official UnoCSS docs for a full setup guide.
- Install UnoCSS and the UI Kit UnoCSS plugin packages
npm i -D unocss @hitachivantara/uikit-uno-preset
- Add them to your
vite.config.ts
and optionally theunocss.config.ts
file.
// vite.config.ts
import unoCSS from "unocss/vite";
import { defineConfig } from "vite";
import { presetHv } from "@hitachivantara/uikit-uno-preset";
export default defineConfig({
plugins: [
unoCSS({
presets: [presetHv()],
}),
],
});
- Add UnoCSS to your app’s entry-file (eg.
main.ts
).
// main.ts
import "virtual:uno.css";
When there isn’t a clear entry-point (ie. micro-frontend with App Shell), you will also need to configure the "per-module"
mode
and add vite-plugin-css-injected-by-js
:
+ cssInjectedByJsPlugin({ relativeCSSInjection: true }),
unoCSS({
+ mode: "per-module",
presets: [presetHv()],
}),
Usage
Note: Usage of an IDE plugin is recommended for a better developer experience.
To use the utility classes, simply add them to a component’s className
prop or to one of the classes
’ keys.
For a list of the available classes, check out the Uno Preset documentation.
Using a cheat sheet can be useful to ease the learning curve of the classes.
Examples
The utility classes integrate with the Design System theme for colors and sizing units:
"p-sm"; // padding `sm` (16px)
"pb-sm"; // padding bottom `sm` (16px)
"my-md"; // margin-y (top+bottom) `md` (24px)
"bg-warning"; // background color of `atmo3`
Sizes and colors
Breakpoints
1
2
3
4
5
6
7
8
9
10
11
12
Overriding classes
object
Animations
Difference from Emotion
To illustrate the code difference from Emotion to UnoCSS, here’s a typical scenario of styling a container and UI Kit component:
-import { css } from "@emotion/css";
-import { theme } from "@hitachivantara/uikit-react-core";
-const classes = {
- container: css({
- display: "flex",
- alignItems: "center",
- gap: theme.space.sm,
- }),
- buttonIcon: css({
- paddingLeft: theme.space.sm,
- color: theme.colors.negative,
- }),
-};
<div
- className={classes.container}
+ className="flex items-center gap-sm"
>
<HvButton
classes={{
- startIcon: classes.buttonIcon,
+ startIcon: "pl-sm text-negative",
}}
/>
<HvTypography />
</div>;