Skip to content

CSS Styles

Benny Powers edited this page May 20, 2022 · 11 revisions

Including styles in your components

For developer ergonomics we separate our CSS from our TS files. This declutters the TS file and helps with syntax highlighting. We then leverage lit-css to import and embed the styles into the component at build time. When making a new component that contains styles, the component should have a corresponding .css file with the identical name as its corresponding .ts file.

Example

rh-footer/
  rh-footer-block.ts
  rh-footer-block.css

rh-footer-block.ts

import style from './rh-footer-block.css';

export class RhFooterBlock extends LitElement {
  static readonly styles = style;
  ...
}

Tokens and Naming Conventions

Red Hat Design Tokens' purpose is bring uniformity of style to the design system while making developers' jobs easier. Lean into it!

Choosing Variables Names

  • DO use existing token names wherever possible
  • ⚠️ AVOID exposing component-specific custom properties
/* GOOD */
border-radius: var(--rh-border-radius-pill, 80px);
/* BAD */
border-radius: var(--rh-jazz-hands-border-radius-pill, 80px);

If you must create a new name for your component:

  • DO use lower-dash-case
  • DON'T use double-dashes
  • DO extend from the general to the specific, left to right
  • ⚠️ AVOID abbreviations or acronyms
  • ⚠️ AVOID 'region' names, use slots and parts instead
/* GOOD */
background-color: var(--rh-jazz-hands-closed-background-color, transparent);
/* BAD */
background-color: var(--rh-c--jazz-hands__m-lg__BackgroundColor_____RedHat, red);

Private Variables

You may use "private custom properties" that are assigned to Shadow DOM elements. Assigning them to private elements in this way lets you do more in-css and less in JavaScript while keeping your element's API surface small.

<header class=${classMap({ mobile })}>
  <button id="close-button">x</button>
  <slot name="header"></slot>
</header>
[part="header"] {
  --offset: var(--rh-space-sm, 8px);
}

[part="header"].mobile {
  --offset: var(--rh-space-xs, 4px);
}

#close-button {
  margin-inline-start: var(--offset);
}

Lightdom CSS

While we encourage developers to style components using the built in scoping method, (i.e. using the styles class field) occasionally we need to include page level styles to target elements that we are unable to style from within the component. We refer to these as "lightdom styles" or "lightdom CSS".

Example

In rh-footer, we need to style the nested <li> and <a> tags within our component to maintain semantic lists. In web components, we are currently unable to style slotted elements that are not that direct children of a component using the ::slotted() sudo selector. To solve this we include a file called rh-footer-lightdom.css.

Including a lightdom CSS file

By default, all .css files are not published in @rhds/elements. This is because the contents of those files are meant to be imported into the web component at build time (see "Including styles in your components" section above). To enable .css files as being able to be packaged add a -lightdom.css to the file name. We include the following publishing pattern in our package.json for this purpose.

{
  "files": [
    "elements/*/*-lightdom.css",
    ...
  ]
}

Make sure that you include instructions for adding this lightdom css file in the documentation for the component.

Clone this wiki locally