C3 AI Documentation Home

Style using scoped CSS

C3 AI Platform's component library comes with detailed and beautiful styling; however, when making custom components, it can be beneficial to ensure that your custom css doesn't affect any other components by accident. For that, you can use *.module.scss files.

Uses

  • Use when you want to add custom css that won't affect any other components.

By default, if you have a very generic css selector like:

Css
  .c3-card {
    font-size: 14px;
  }

This style will be applied to every component with the c3-card class whenever a component that imports that css style is added to the page. The downside of this behavior is that you always need to be careful with the way to write your css selectors since they will "leak out" into the rest of the page.

When you use *.module.scss, this does not happen. Even if that component imports a scss module that has very generic selectors like c3-card, UI framework will make sure the styles are automatically scoped to only affect the component and not leak into other components in the same page.

Limitations

  • Only classNames and ids defined in the *.module.scss file will not affect other components, elements that add styling here will act as normal unless wrapped in a className or ID.
  • To get the benefit of *.module.scss files, styles needs to be imported from the file and then used with the classNames or ids. See the example below for more info.
  • classNames that are used in *.module.scss files are encoded at runtime, making them difficult to override and not human-readable.
  • classNames/ids that want to use *.module.scss stylings, need to directly import or be passed styles. classNames that are not used with styles will not be able to utilize the styles.

Example

The following shows an example of how SDLDemo.CustomPageWithExternalLibrary.tsx uses CustomInfoPage.module.scss to ensure that only SDLDemo.CustomPageWithExternalLibrary.tsx uses the styles.

CSS

First, CustomInfoPage.module.scss is defined as normal using .c3-card to give styles specific to that className.

Css
// CustomInfoPage.module.scss

.c3-card {
  background-color: #111;
  padding: 16px;
  margin: 0 8px;
  color: #ccc;
  font-size: medium;
  font-family:'Times New Roman', Times, serif;
  border: solid salmon;
}

.explanation-area {
  margin-right: 8px !important;
  margin-left: -8px !important;
}

React

CustomInfoPage.module.scss is then imported into the React component with import styles from '@c3/ui/CustomInfoPage.module.scss'. styles is then used to actually get the style for each className with styles['c3-card'] as an example.

TypeScript
// SDLDemo.CustomPageWithExternalLibrary.tsx
import * as React from 'react';
import Grid from '@material-ui/core/Grid'
import styles from '@c3/ui/CustomInfoPage.module.scss';
import '@c3/css-library/components/base/_card.scss';

const CustomInfoPage = () => {

  return (
    <div>
      <Grid container spacing={24}>
        <Grid item xs={12} className={styles["explanation-area-two"]}>
          <div className={styles["c3-card"]} style={{height: '100%'}}>
            <p className={styles["explanation-text"]}> This entire page is using a React only custom component, meaning
            that only a single tsx file exists for the content of page (outside of the nav menu). It also uses module.scss
            rather than plain .scss for styling. That means that this text area looks quite different compared to the other
            'c3-card' className areas in the C3 AI UI Component Library. In fact, only 'c3-card' areas using this module.scss
            file will look like this text area, while the other text area uses our default `_card.scss` that is used in many
            components for a more uniform look across the application. This can be helpful for making styles that are very unique
            to one component while using more general classNames without worrrying about the styles 'spilling over' into 
            other components. However, with this, it's important to remember that customizing css in this way can make a component
            look out of place in the large scheme of the application if not handled properly.</p>
          </div>
        </Grid>

      </Grid>
    </div>
  )
}

export default CustomInfoPage;

Below, you can see an image of how this component looks on the screen and the generated className from the component does not match c3-card as we would normally expect. Resulting application

Was this page helpful?