Skip to content

Styling and Shadowing

Overview

Chicago Docs was designed to be as easy as possible to customize for the largest number of users. You can re-style components using plain CSS or SASS. You can also style and customize components using JavaScript and Theme-UI.

In Gatsby, customizing, altering, or replacing styles and components is called shadowing. Shadowing a theme file means creating a file in your site directory that will override the one from the theme.

To shadow a file, the new file should have the same name as the one you're shadowing but a slightly different path:

  1. In the src directory of your site, create nested directories for the namespace and name of the original theme: your-site/src/namespace/theme-name/. If the theme is not namespaced, omit the namespace directory: your-site/src/theme-name.
  2. In this new theme directory, re-create the file path of the original file, but omit the original src directory: your-site/src/namespace/theme-name/components/.
  3. Create a file with the same name as the file you're shadowing: src/namespace/theme-name/components/component.js.

So if the file path in the original theme is namespace/theme-name/src/components/component.js, the shadowed file path should be your-site/src/namespace/theme-name/components/component.js.

For example, the Chicago Docs Alert component has a file path of

@kabartolo
└── gatsby-theme-chicago-docs
└── src
└── components
└── Alert
└──index.js

To shadow the Alert component, create a file with the following path, starting from your site directory:

your-site
└── src
└── @kabartolo
└── gatsby-theme-chicago-docs
└── components
└── Alert
└──index.js

Components

React components in a Gatsby theme can be shadowed as described in the previous section.

As an example, we'll shadow the Alert component to change its default color variant. The Alert component creates a colored box around the text you provide it. In the live preview below, try deleting variant="error". With no variant specified, the Alert component will use the default color variant information, which is blue.

To change the default color to the error variant instead, do the following:

  1. In your site directory, create an index.js file with a path as shown:
your-site
└── src
└── @kabartolo
└── gatsby-theme-chicago-docs
└── components
└── Alert
└──index.js
  1. Copy and paste the contents of the original Alert/index.js file into your new Alert/index.js file:

your-site/src/@kabartolo/.../index.js

JSX
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/** @jsx jsx */
import { jsx } from 'theme-ui';
import PropTypes from 'prop-types';
import styles from './alert.module.scss';
export default function Alert({ children, variant }) {
return (
<aside className={`chicago-alert ${styles.alert}`} sx={{ variant: `alerts.${variant}` }}>
{children}
</aside>
);
}
Alert.propTypes = {
children: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.node),
PropTypes.node,
]).isRequired,
variant: PropTypes.string,
};
Alert.defaultProps = {
variant: 'information',
};
  1. Line 5 above will cause a ReferenceError if alert.module.scss doesn't exist in this file's directory. Import this file from @kabartolo/gatsby-theme-chicago-docs instead:

your-site/src/@kabartolo/.../index.js

JSX
1
2
3
4
5
6
7
8
/** @jsx jsx */
import { jsx } from 'theme-ui';
import PropTypes from 'prop-types';
import styles from '@kabartolo/gatsby-theme-chicago-docs/src/components/Alert/alert.module.scss';
// code omitted for brevity
  1. Finally, change the default value for the variant prop to 'error':

your-site/src/@kabartolo/.../index.js

JSX
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/** @jsx jsx */
import { jsx } from 'theme-ui';
import PropTypes from 'prop-types';
import styles from '@kabartolo/gatsby-theme-chicago-docs/src/components/Alert/alert.module.scss';
export default function Alert({ children, variant }) {
return (
<aside className={`chicago-alert ${styles.alert}`} sx={{ variant: `alerts.${variant}` }}>
{children}
</aside>
);
}
Alert.propTypes = {
children: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.node),
PropTypes.node,
]).isRequired,
variant: PropTypes.string,
};
Alert.defaultProps = {
variant: 'error',
};

All Alert boxes that don't specify a variant will now use the error color scheme (red).

CSS

Overview

Most styles in this theme are written in SASS and defined in CSS modules. See Global styles below to work with regular CSS and stylesheets.

Most components in this theme have a corresponding CSS module, and there is also a global SASS file where the SASS variables are defined.

@kabartolo
└──gatsby-theme-chicago-docs
└── src
└── components
└── List
├── index.js
└── list.module.scss
└── styles
└── _global.scss

In Chicago Docs, each module is imported into the React component as a styles object containing the class names for the module:

list.js

JSX
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import React from 'react';
import styles from './list.module.scss';
export default function List({ items }) {
return (
<ul className={styles.list}>
{items.map((item) => (
<li key={item.id} className={styles.listItem}>
{item.text}
</li>
))}
</ul>
);
}

These class names are written in camel case in the styles object, such as styles.listItem or styles.leftColumn. However, in the CSS file, they are written in hyphenated lowercase. For example, styles.listItem should be referenced as .list-item in the CSS module file:

list.module.scss

SASS
1
2
3
4
5
6
7
.list {
list-style: 'none',
}
.list-item {
padding-left: 1em;
}

Note that the 'list-item' class from the List module will be called something like this in the browser: list-module--list-item-KDSJ4 (where the string of characters at the end is random).

Shadowing

Shadowing is the best way to alter CSS-module styles. For example, to change the padding on the Toggle component, do the following:

  1. Create a new toggle.module.scss file in your site folder with the path of the Toggle component:
your-site
└── src
└── @kabartolo
└── gatsby-theme-chicago-docs
└── components
└── Layout
└── Toggle
└──toggle.module.scss
  1. Copy and paste the original contents of the theme's toggle.module.scss into this new file. Adjust the padding value (import the _global.scss file to use any SASS variables):

your-site/src/@kabartolo/.../toggle.module.scss

SASS
1
2
3
4
5
6
@import '@kabartolo/gatsby-theme-chicago-docs/src/styles/_global.scss';
.button {
padding: $toggle-padding-variant;
cursor: pointer;
}

The Toggle component's padding value has now changed to the value of $toggle-padding-variant.

Global styles

All Chicago Docs components contain regular class names in addition to CSS-module class names. You can create a custom stylesheet for your site and override any style by selecting the appropriate class name.

To make several style changes throughout the site, create a stylesheet and import it into a shadowed Layout component. The Layout component handles the global styles for the site. See Standard Styling with Global CSS files for guidance.

To make just a few changes, shadow just the Layout's CSS module file (layout.module.scss) and reference global class names using :global(.class-name):

your-site/src/@kabartolo/.../layout.module.scss

SASS
@import '@kabartolo/gatsby-theme-chicago-docs/src/styles/_global.scss';
.main-wrapper {
// code omitted for brevity
}
:global(.article-container) {
@include for-desktop-up {
padding: 0 20vw;
}
@include for-desktop-under {
padding: 0 15vw;
}
@include for-mobile-only {
padding: 0 5vw;
}
}
:global(.toc-container) {
border: none !important;
box-shadow: none !important;
:global(.toc-title) {
font-size: 1.3rem !important;
}
}

Theme-UI

Overview

While most CSS styles are defined in CSS modules, any reusable site colors, borders, fonts, and other decorative styles are defined in a Theme-UI object using JavaScript syntax. These are the styles that form a consistent look and feel for your site and are used to display MDX. Theme-UI also takes care of the dark and light color themes for the site.

Shadowing

The Theme-UI files for Chicago Docs can be shadowed like any other file. Refer to the Chicago Docs Theme-UI Reference object to get the key for the style you want to shadow. For example, to change the background color of an Alert component variant, refer to the colors object of the theme:

Theme-UI object

JSON
"colors": {
"text": "#454f5b",
"background": "#fff",
"primary": "#5c6ac4",
"secondary": "#5b69cb",
"highlight": "#d3d7f0",
"muted": "#e6e6e6",
"gray": "#dfe3e8",
"accent": "#f49342",
"darken": "#00044c",
"modes": {
"dark": {
"text": "#fff",
"background": "#000639",
"primary": "#5e96ff",
"secondary": "#5e96ff",
"highlight": "#023751",
"muted": "#454f5b",
"gray": "#3e4155",
"backgroundSecondary": "#3e4155",
"border": "#454f5b",
"siteTitle": "#5e96ff",
"siteTitleHover": "#fff",
"alertLink": "#000639",
"informationBackground": "#2e5aac",
"successBackground": "#287d3c",
"warningBackground": "#b95000",
"errorBackground": "#da1414"
}
},
"backgroundSecondary": "#fff",
"border": "#e6e6e6",
"siteTitle": "#003049",
"siteTitleHover": "#5b69cb",
"alertLink": "#5b69cb",
"informationBackground": "#eef2fa",
"informationBorder": "#89a7e0",
"successBackground": "#edf9f0",
"successBorder": "#5aca75",
"warningBackground": "#fff4ec",
"warningBorder": "#ff8f39",
"errorBackground": "#feefef",
"errorBorder": "#f48989"
},

The background colors for the Alert component's warning variant are defined in colors.warningBackground and colors.modes.dark.warningBackground for the light and dark theme modes, respectively. This example will change these background colors.

  1. To shadow the Theme-UI file, in the root of your site folder, create a file called index.js with the following path:
your-site
└── src
└── gatsby-plugin-theme-ui
└── index.js
  1. To avoid having to copy and paste the entire theme object, import the base theme and Theme-UI's merge function:

your-site/src/gatsby-plugin-theme-ui/index.js

JavaScript
1
2
import { merge } from 'theme-ui';
import baseTheme from '@kabartolo/gatsby-theme-chicago-docs/src/gatsby-plugin-theme-ui';
  1. Specify new values for the warning variant colors, and merge them with the base theme:

your-site/src/gatsby-plugin-theme-ui/index.js

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
import { merge } from 'theme-ui';
import baseTheme from '@kabartolo/gatsby-theme-chicago-docs/src/gatsby-plugin-theme-ui';
export default merge(baseTheme, {
colors: {
warningBackground: '#ff6600',
modes: {
dark: {
warningBackground: '#c24e00',
},
},
},
});

The original variants and styles will be merged with these new colors, which will take precedence over the original colors. All other theme values will stay the same.

Typography

Chicago Docs uses the noriega Typography.js theme. To use a different Typography.js theme, shadow gatsby-plugin-theme-ui and add the new theme. The new theme will override the original.

This example will replace the noriega theme with the funston theme.

  1. Install the new Typography theme to your site:

Install typography-theme-funston

npm install --save typography-theme-funston
  1. Import the theme into the shadowed gatsby-plugin-theme-ui file. Also import Theme-UI's toTheme function to make the Typography.js theme compatible with Theme-UI:

your-site/src/gatsby-plugin-theme-ui/index.js

JavaScript
1
2
3
4
5
import { merge } from 'theme-ui';
import baseTheme from '@kabartolo/gatsby-theme-chicago-docs/src/gatsby-plugin-theme-ui';
import { toTheme } from '@theme-ui/typography';
import funstonTheme from 'typography-theme-funston';
  1. Convert the theme to a Theme-UI object with the toTheme function, and add it to the merged theme object using the spread operator (...):

site/src/gatsby-plugin-theme-ui/index.js

JavaScript
1
2
3
4
5
6
7
8
9
10
11
import { merge } from 'theme-ui';
import baseTheme from '@kabartolo/gatsby-theme-chicago-docs/src/gatsby-plugin-theme-ui';
import { toTheme } from '@theme-ui/typography';
import funstonTheme from 'typography-theme-funston';
const typography = toTheme(funstonTheme);
export default merge(baseTheme, {
...typography,
});

Prism-JS

The theme currently uses the nightOwl and nightOwlLight code-highlighting presets from Prism.js. They are used for the dark and default (light) color modes, respectively. These presets are listed in the prism key of the Theme-UI object.

This example will change these presets respectively to duotoneDark and duotoneLight.

  1. Install the presets from prism-react-renderer:

Install the presets

npm install --save prism-react-renderer/themes/duotone-dark prism-react-renderer/themes/duotone-light
  1. Import the presets into the shadowed gatsby-plugin-theme-ui file. There should be one preset for each color mode on your site (e.g., a dark and light preset):

your-site/src/gatsby-plugin-theme-ui/index.js

JavaScript
1
2
3
4
5
import { merge } from 'theme-ui';
import baseTheme from '@kabartolo/gatsby-theme-chicago-docs/src/gatsby-plugin-theme-ui';
import duotoneDark from 'prism-react-renderer/themes/duotone-dark';
import duotoneLight from 'prism-react-renderer/themes/duotone-light';
  1. Add the preset(s) to the prism key of the merged theme object. The color modes in Chicago Docs are dark and default (light):

your-site/src/gatsby-plugin-theme-ui/index.js

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
import { merge } from 'theme-ui';
import baseTheme from '@kabartolo/gatsby-theme-chicago-docs/src/gatsby-plugin-theme-ui';
import duotoneDark from 'prism-react-renderer/themes/duotone-dark';
import duotoneLight from 'prism-react-renderer/themes/duotone-light';
export default merge(baseTheme, {
prism: {
dark: duotoneDark,
default: duotoneLight,
},
});

All code blocks on the site should now be highlighted using the new Prism themes.

Reference

The following is a record of the Theme-UI theme object with all values currently defined by @kabartolo/gatsby-theme-chicago-docs.

Reference Theme-UI object

JSON
{
"space": [
0,
7,
14,
28,
56,
112,
224
],
"fonts": {
"body": "'Lato', sans-serif",
"heading": "'Lato', sans-serif",
"moonospace": "Menlo, monospace"
},
"fontSizes": [
15.580412437079403,
16.348458215797965,
18,
21.820460514776034,
24.024790844584096,
29.124000000000002
],
"fontWeights": {
"body": 400,
"heading": 700,
"bold": 700
},
"lineHeights": {
"body": 1.61,
"heading": 1.1
},
"colors": {
"text": "#454f5b",
"background": "#fff",
"primary": "#5c6ac4",
"secondary": "#5b69cb",
"highlight": "#d3d7f0",
"muted": "#e6e6e6",
"gray": "#dfe3e8",
"accent": "#f49342",
"darken": "#00044c",
"modes": {
"dark": {
"text": "#fff",
"background": "#000639",
"primary": "#5e96ff",
"secondary": "#5e96ff",
"highlight": "#023751",
"muted": "#454f5b",
"gray": "#3e4155",
"backgroundSecondary": "#3e4155",
"border": "#454f5b",
"siteTitle": "#5e96ff",
"siteTitleHover": "#fff",
"alertLink": "#000639",
"informationBackground": "#2e5aac",
"successBackground": "#287d3c",
"warningBackground": "#b95000",
"errorBackground": "#da1414"
}
},
"backgroundSecondary": "#fff",
"mediumGray": "grey",
"border": "#e6e6e6",
"borderFocus": "rgba(3,102,214,.3)",
"siteTitle": "#003049",
"siteTitleHover": "#5b69cb",
"alertLink": "#5b69cb",
"informationBackground": "#eef2fa",
"informationBorder": "#89a7e0",
"successBackground": "#edf9f0",
"successBorder": "#5aca75",
"warningBackground": "#fff4ec",
"warningBorder": "#ff8f39",
"errorBackground": "#feefef",
"errorBorder": "#f48989"
},
"styles": {
"root": {
"fontFamily": "body",
"lineHeight": "body",
"fontWeight": "body"
},
"h1": {
"color": "text",
"fontFamily": "heading",
"lineHeight": "heading",
"fontWeight": "heading",
"fontSize": 5
},
"h2": {
"color": "text",
"fontFamily": "heading",
"lineHeight": "heading",
"fontWeight": "heading",
"fontSize": 4
},
"h3": {
"color": "text",
"fontFamily": "heading",
"lineHeight": "heading",
"fontWeight": "heading",
"fontSize": 3
},
"h4": {
"color": "text",
"fontFamily": "heading",
"lineHeight": "heading",
"fontWeight": "heading",
"fontSize": 2
},
"h5": {
"color": "text",
"fontFamily": "heading",
"lineHeight": "heading",
"fontWeight": "heading",
"fontSize": 1
},
"h6": {
"color": "text",
"fontFamily": "heading",
"lineHeight": "heading",
"fontWeight": "heading",
"fontSize": 0
},
"p": {
"color": "text",
"fontFamily": "body",
"fontWeight": "body",
"lineHeight": "body"
},
"a": {
"color": "primary"
},
"pre": {
"fontFamily": "monospace",
"overflowX": "auto",
"code": {
"color": "inherit"
},
"marginTop": 0
},
"code": {
"fontFamily": "monospace",
"fontSize": "inherit"
},
"table": {
"width": "100%",
"borderCollapse": "separate",
"borderSpacing": 0,
"margin": "1rem 0 2em 0",
"display": "block",
"overflow": "auto"
},
"th": {
"textAlign": "left",
"borderBottomStyle": "solid",
"padding": "1rem 2rem"
},
"td": {
"textAlign": "left",
"borderBottomStyle": "solid",
"borderBottom": "1px solid",
"padding": "1rem 2rem"
},
"img": {
"maxWidth": "100%"
},
"inlineCode": {
"bg": "highlight",
"fontSize": "1rem"
}
},
"typography": {
"options": {
"baseFontSize": 18,
"baseLineHeight": 1.61,
"headerLineHeight": 1.1,
"scaleRatio": 1.618,
"googleFonts": [
{
"name": "Lato",
"styles": [
"400",
"700"
]
}
],
"headerFontFamily": [
"Lato",
"sans-serif"
],
"bodyFontFamily": [
"Lato",
"sans-serif"
],
"headerWeight": 700,
"bodyWeight": 400,
"boldWeight": 700,
"includeNormalize": true,
"blockMarginBottom": 1,
"title": "Noriega",
"rhythmUnit": "px"
}
},
"prism": {
"dark": {
"plain": {
"color": "#d6deeb",
"backgroundColor": "#011627"
},
"styles": [
{
"types": [
"changed"
],
"style": {
"color": "rgb(162, 191, 252)",
"fontStyle": "italic"
}
},
{
"types": [
"deleted"
],
"style": {
"color": "rgba(239, 83, 80, 0.56)",
"fontStyle": "italic"
}
},
{
"types": [
"inserted",
"attr-name"
],
"style": {
"color": "rgb(173, 219, 103)",
"fontStyle": "italic"
}
},
{
"types": [
"comment"
],
"style": {
"color": "rgb(99, 119, 119)",
"fontStyle": "italic"
}
},
{
"types": [
"string",
"url"
],
"style": {
"color": "rgb(173, 219, 103)"
}
},
{
"types": [
"variable"
],
"style": {
"color": "rgb(214, 222, 235)"
}
},
{
"types": [
"number"
],
"style": {
"color": "rgb(247, 140, 108)"
}
},
{
"types": [
"builtin",
"char",
"constant",
"function"
],
"style": {
"color": "rgb(130, 170, 255)"
}
},
{
"types": [
"punctuation"
],
"style": {
"color": "rgb(199, 146, 234)"
}
},
{
"types": [
"selector",
"doctype"
],
"style": {
"color": "rgb(199, 146, 234)",
"fontStyle": "italic"
}
},
{
"types": [
"class-name"
],
"style": {
"color": "rgb(255, 203, 139)"
}
},
{
"types": [
"tag",
"operator",
"keyword"
],
"style": {
"color": "rgb(127, 219, 202)"
}
},
{
"types": [
"boolean"
],
"style": {
"color": "rgb(255, 88, 116)"
}
},
{
"types": [
"property"
],
"style": {
"color": "rgb(128, 203, 196)"
}
},
{
"types": [
"namespace"
],
"style": {
"color": "rgb(178, 204, 214)"
}
}
]
},
"default": {
"plain": {
"color": "#403f53",
"backgroundColor": "#FBFBFB"
},
"styles": [
{
"types": [
"changed"
],
"style": {
"color": "rgb(162, 191, 252)",
"fontStyle": "italic"
}
},
{
"types": [
"deleted"
],
"style": {
"color": "rgba(239, 83, 80, 0.56)",
"fontStyle": "italic"
}
},
{
"types": [
"inserted",
"attr-name"
],
"style": {
"color": "rgb(72, 118, 214)",
"fontStyle": "italic"
}
},
{
"types": [
"comment"
],
"style": {
"color": "rgb(152, 159, 177)",
"fontStyle": "italic"
}
},
{
"types": [
"string",
"builtin",
"char",
"constant",
"url"
],
"style": {
"color": "rgb(72, 118, 214)"
}
},
{
"types": [
"variable"
],
"style": {
"color": "rgb(201, 103, 101)"
}
},
{
"types": [
"number"
],
"style": {
"color": "rgb(170, 9, 130)"
}
},
{
"types": [
"punctuation"
],
"style": {
"color": "rgb(153, 76, 195)"
}
},
{
"types": [
"function",
"selector",
"doctype"
],
"style": {
"color": "rgb(153, 76, 195)",
"fontStyle": "italic"
}
},
{
"types": [
"class-name"
],
"style": {
"color": "rgb(17, 17, 17)"
}
},
{
"types": [
"tag"
],
"style": {
"color": "rgb(153, 76, 195)"
}
},
{
"types": [
"operator",
"property",
"keyword",
"namespace"
],
"style": {
"color": "rgb(12, 150, 155)"
}
},
{
"types": [
"boolean"
],
"style": {
"color": "rgb(188, 84, 84)"
}
}
]
}
},
"breakpoints": [
"52em",
"62em",
"82em"
],
"shadows": {
"main": "0 0 2px rgba(0,0,0,0.05),0 1px 4px rgba(0,0,0,0.05)",
"search": "inset 0 1px 2px rgba(27,31,35,.075)",
"searchFocus": "inset 0 1px 2px #d1d5da, 0 0 0 .2em rgba(3,102,214,.3)"
},
"alerts": {
"error": {
"bg": "errorBackground",
"borderLeft": "thickest",
"borderColor": "errorBorder",
"a": {
"color": "alertLink"
}
},
"information": {
"bg": "informationBackground",
"borderLeft": "thickest",
"borderColor": "informationBorder",
"a": {
"color": "alertLink"
}
},
"success": {
"bg": "successBackground",
"borderLeft": "thickest",
"borderColor": "successBorder",
"a": {
"color": "alertLink"
}
},
"warning": {
"bg": "warningBackground",
"borderLeft": "thickest",
"borderColor": "warningBorder",
"a": {
"color": "alertLink"
}
}
},
"buttons": {
"default": {
"border": "none",
"bg": "inherit",
"color": "text",
"cursor": "pointer",
"fontWeight": "body",
"outline": "none"
}
},
"borders": {
"main": "1px solid",
"thick": "1.5px solid",
"thicker": "4px solid",
"thickest": "7px solid"
},
"icons": {
"default": {
"fontSize": "1.5rem",
"color": "text",
"margin": "0 15px"
}
},
"links": {
"layout": {
"fontSize": "1.1rem",
"textDecoration": "none",
"color": "primary",
"fontWeight": "heading",
":hover": {
"textDecoration": "underline"
}
},
"hover": {
"color": "text",
"textDecoration": "none",
"fontWeight": "body",
":hover": {
"color": "secondary",
"textDecoration": "underline"
}
}
},
"listItems": {
"layout": {
"listStyle": "none"
}
}
}