DocsStyling

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.

  1. Install UnoCSS and the UI Kit UnoCSS plugin packages
npm i -D unocss @hitachivantara/uikit-uno-preset
  1. Add them to your vite.config.ts and optionally the unocss.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()],
    }),
  ],
});
  1. 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>;