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
primaryandsecondary. - 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:
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):
{
"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:
{
"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:
{
"ref": {
"typeface": {
"fontFamily": "Avenir Next, sans-serif, PingFang SC, Microsoft YaHei",
"htmlFontSize": "100%",
"fontWeightLight": 300,
"fontWeightRegular": 400,
"fontWeightMedium": 500,
"fontWeightSemiBold": 600,
"fontWeightBold": 700,
"customFonts": []
}
}
}font: Ordered font stack (include system fallbacks).Family html: Root HTML font size (affects rem scaling).Font Size font: Weight scale applied across typographic levels.Weight* custom: Register custom web fonts. Lear more in using custom fonts.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:
{
"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:
{
"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:
{
"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:
{
"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:
{
"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:
{
"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:
{
"sys": {
"color": {
"mode": "light",
"light": {
"shape": {
"shape1": "2px",
"shape2": "4px",
"inputField": "2px"
}
}
}
}
}shape1: Small components (buttons, inputs).shape2: Larger containers (cards, dialogs).input: Specifically for input elements (distinct when shape1 is more rounded).Field
Shadow
Controls shadow effects for depth:
{
"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.
{
"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.
{
"src": {
"primary": {
"color": "green",
"harmonize": true
}
}
}If secondary is not defined, it will be generated from primary. Setting harmonize 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: