Skip to content

Customizing theme options is the recommended way to create new themes. ArcGIS Experience Builder theme module is built on a structured Theme Design System so you can adjust brand colors, typography, surfaces, and interaction states without writing custom CSS.

1. Define core theme layers

When customizing theme options, you first define values in three conceptual layers: Source, Reference, and System:

  • Start with the source layer, such as brand and neutral, for rapid theming and automatic light/dark support. Learn more in the source layer.
  • Adjust the reference layer only for specialized typography or palette needs. Learn more in the reference layer.
  • Use the system layer for fine-grained surface, action, and semantic overrides. Learn more in the system layer.

2. Minimize overrides

When customizing theme options:

  • Keep your overrides minimal to preserve configurability in Theme settings.
  • Overriding too many options can lead to a rigid theme that is hard to maintain.
  • Focus on key brand elements and only adjust system tokens when necessary.

3. Validate accessibility

As you customize theme options, ensure that your theme meets accessibility standards. Check color contrast ratios for text and interactive elements, and verify that font sizes and weights are legible across different devices and screen sizes.

Core theme layers

When you customize a theme, you typically work with three conceptual layers that build upon each other:

  • Source layer: Defines base colors like brand and neutral.
  • Reference layer: Builds on source for palette and typography.
  • System layer: Provides semantic tokens for surfaces, actions, and typography.

Source layer (base colors)

The Source layer is the foundation of the theme's color system, defining the core color sources. It includes:

  • Brand colors: Includes primary and secondary.
  • Neutral colors: Used for backgrounds, text, and borders.
  • Functional colors: Used to indicate status such as error, warning, info, and success.

The interface of theme source option is:

Use dark colors for code blocksCopy
1
2
3
4
interface ThemeSourceOption {
  color: string // Color value (Hex or RGB).
  harmonize?: boolean // Whether to harmonize derived colors to avoid low contrast.
}

By simply customizing the primary color, a complete theme is generated. In this example, a fresh green theme is created.

If secondary ThemeSourceOption is not defined, it will be automatically generated based on the primary ThemeSourceOption.

Functional color

Default values (usually no need to modify unless necessary):

Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
{
  "src": {
    "error": { "color": "#B3261E", "harmonize": true },
    "warning": { "color": "#C77E00", "harmonize": true },
    "info": { "color": "#0073AC", "harmonize": true },
    "success": { "color": "#00551E", "harmonize": true }
  }
}

Neutral colors

Defaults to grayscale tones. You can mix hues via harmonize for different atmospheres:

Use dark colors for code blocksCopy
1
2
3
4
5
{
  "src": {
    "neutral": { "color": "orange", "harmonize": true }
  }
}

This creates a warm-toned theme with orange accents.

Best practices

  • When changing brand or neutral colors, verify text/background contrast meets WCAG AA (4.5:1 for normal text, 3:1 for large text).
  • Modifying only the source layer automatically supports both light and dark modes.

Reference layer

The reference layer builds upon the source layer to define the Palette and Typeface of the theme.

  • The Palette in the Reference Layer is auto-generated from the source layer. Usually no manual adjustment is required unless you have highly specific needs.
  • The Typeface allows you to customize font families, sizes, and weights used throughout the theme.

For example, to customize the typeface, you can define the following in your theme options:

Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
  "ref": {
    "typeface": {
      "fontFamily": "Avenir Next, sans-serif, PingFang SC, Microsoft YaHei",
      "htmlFontSize": "100%",
      "fontWeightLight": 300,
      "fontWeightRegular": 400,
      "fontWeightMedium": 500,
      "fontWeightSemiBold": 600,
      "fontWeightBold": 700,
      "customFonts": []
    }
  }
}
  • fontFamily: Ordered font stack (include system fallbacks).
  • htmlFontSize: Root HTML font size (affects rem scaling).
  • fontWeight*: Weight scale applied across typographic levels.
  • customFonts: Register custom web fonts. Lear more in using custom fonts.

System layer

The system layer serves as the semantic description of the theme. The following options can be used to customize system-layer variables.

  • Color: Brand, functional, surface, divider, and action semantics.
  • Shape: Border radius tokens.
  • Shadow: Elevation depth styles.
  • Typography: Semantic text levels (headings, body, labels, input).

Color

The color system in the system layer is structured into several semantic groups:

Brand colors (primary and secondary)

Derived from the source layer but can be further adjusted here:

Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
  "sys": {
    "color": {
      "mode": "light",
      "light": {
        "primary": {
          "main": "#005faf",
          "light": "#0078da",
          "dark": "#004786",
          "text": "#ffffff"
        }
      }
    }
  }
}
  • main: Main brand color.
  • light/dark: Lighter and darker variants.
  • text: Text/icon color on the color background.
Functional colors

For statuses like info, success, warning, and error. Defaults are from source but can be overridden:

Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
  "sys": {
    "color": {
      "mode": "light",
      "light": {
        "error": {
          "main": "#b4271f",
          "light": "#d74034",
          "dark": "#910809",
          "text": "#ffffff"
        }
      }
    }
  }
}
Surface colors

Used for backgrounds and containers, derived from neutral colors:

Use dark colors for code blocksCopy
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
{
  "sys": {
    "color": {
      "mode": "light",
      "light": {
        "surface": {
          "background": "#f2f0f0",
          "backgroundText": "#000000",
          "backgroundHint": "#2f3031",
          "paper": "#faf9f9",
          "paperText": "#1b1c1c",
          "paperHint": "#464747",
          "overlay": "#ffffff",
          "overlayText": "#2f3031",
          "overlayHint": "#5e5e5e",
          "header": "#ffffff",
          "headerText": "#000000",
          "headerHint": "#2f3031",
          "footer": "#f2f0f0",
          "footerText": "#000000",
          "footerHint": "#5e5e5e"
        }
      }
    }
  }
}
  • Background: Page background.
  • Paper: Panels, widgets, cards, modals.
  • Overlay: Top-level containers.
  • Header: Used for page header.
  • Footer: Used for page footer.

Each surface has:

  • Text: Default text/icon color.
  • Hint: Lighter secondary text color.
Divider colors

Used for borders and dividers:

Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
  "sys": {
    "color": {
      "mode": "light",
      "light": {
        "divider": {
          "primary": "#ababab",
          "secondary": "#c7c6c6",
          "tertiary": "#e3e2e2",
          "input": "#ababab",
          "switch": "#919191",
          "inputField": "#ababab"
        }
      }
    }
  }
}
Action colors

Used for interactive states like hover, selected, disabled, and links:

Use dark colors for code blocksCopy
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
27
28
29
{
  "sys": {
    "color": {
      "mode": "light",
      "light": {
        "action": {
          "default": "#faf9f9",
          "hover": "#e3e2e2",
          "text": "#000000",
          "disabled": {
            "default": "#e3e2e2",
            "text": "#ababab"
          },
          "focus": "#0078da",
          "selected": {
            "default": "#005faf",
            "hover": "#004786",
            "text": "#ffffff"
          },
          "link": {
            "default": "#005faf",
            "hover": "#004786",
            "visited": "#464747"
          }
        }
      }
    }
  }
}

Interactive states include:

  • Default: Base background for interactive elements.
  • Hover: Background on pointer hover.
  • Text: Foreground (text/icon) color on interactive backgrounds.
  • Disabled: Colors for non-interactive states.
  • Focus: Focus outline/ring color.
  • Selected: Background/hover/text for selected items.
  • Link: Default/hover/visited link colors.

By default, gray tones are used for action states, but you can integrate brand and functional colors for richer palettes.

Excessive overrides in action colors may reduce visual consistency; prefer source layer adjustments when possible.

Color mode

Color settings in the system layer support both light and dark modes:

Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
9
{
  "sys": {
    "color": {
      "mode": "light",
      "light": { "primary": { ... } },
      "dark": { "primary": { ... } }
    }
  }
}

The "mode" field sets the current color mode. Both modes can be configured, and the system switches automatically.

Shape (corner radius)

Controls component border radius:

Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
  "sys": {
    "color": {
      "mode": "light",
      "light": {
        "shape": {
          "shape1": "2px",
          "shape2": "4px",
          "inputField": "2px"
        }
      }
    }
  }
}
  • shape1: Small components (buttons, inputs).
  • shape2: Larger containers (cards, dialogs).
  • inputField: Specifically for input elements (distinct when shape1 is more rounded).

Shadow

Controls shadow effects for depth:

Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
  "sys": {
    "color": {
      "mode": "light",
      "light": {
        "shadow": {
          "shadow1": "0 0 10px 1px rgba(0,0,0,0.2)",
          "shadow2": "0 0 6px 0 rgba(0,0,0,0.15)",
          "shadow3": "0 0 20px 2px rgba(0,0,0,0.2)"
        }
      }
    }
  }
}

Use a limited set of shadow tokens to maintain consistent elevation. Avoid very dark large blurs which can reduce legibility.

Typography

Defines text styles for different levels:

  • H1-H3: Designed for succinct and prominent text or numerals.
  • H4-H6: Ideal for showcasing brief, yet highly emphasized text on compact screens.
  • Titles: Employed for concise, moderately emphasized text.
  • Body: Used for extended paragraphs of text throughout the page.
  • InputField: Used for text display in input-related components, such as text inputs, selectors, etc.
  • Labels: Compact text for auxiliary hints or embedded metadata.
Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
  "sys": {
    "color": {
      "mode": "light",
      "light": {
        "typography": {
          "h1": { "fontFamily": "Avenir Next", "fontWeight": 400, "fontSize": "3rem", "lineHeight": 1.167 },
          ...
          "label3": { "fontFamily": "Avenir Next", "fontWeight": 400, "fontSize": "0.625rem", "lineHeight": 1.8 }
        }
      }
    }
  }
}

Code examples

Create a theme with brand colors

To generate a custom theme, you can start by overriding only the primary brand color in the source layer. All derived palette tokens will be auto-generated.

Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
{
  "src": {
    "primary": {
      "color": "green",
      "harmonize": true
    }
  }
}

If secondary is not defined, it will be generated from primary. Setting harmonize: true adjusts related neutrals and functional tones for better contrast.

What's next?

Learn about the different theme development options and how to create and customize themes:

Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.