Tutorials/Power Apps/Power Apps Theming: Build a Consistent UI with a Central Style Collection
Power Appsintermediate

Power Apps Theming: Build a Consistent UI with a Central Style Collection

Learn how to centralize your app’s color palette, typography, icon set, and control defaults into a reusable style library that keeps every screen on brand.

NA
Narmer Abader
@narmer · Published June 3, 2026

Ever found yourself clicking through a dozen screens just to change one button color? Or noticing that your app’s headers use different font sizes because you typed the value directly? By creating a single global “theme” object, you can define every visual choice in one place and reference it everywhere. This article walks through building your own theme for colors, typography, icons, and control properties in Power Apps.

Scenario: A CRM with Consistent Branding

Imagine you’re building a customer relationship management (CRM) app for a fictional company called Northwind Traders. The brand uses a deep blue (#2E86AB) as primary, a warm coral (#A23B72) as secondary, and a set of neutral grays. Headings should be rendered in the “Segoe UI” font, body text in “Roboto”, and icons should come from a curated set of Fluent UI SVG paths.

Your job is to ensure every screen respects these rules without manually updating each control.

Step 1: Build a Color Palette

Your palette should cover brand colors, semantic status colors (success, warning, danger, info), and a full gray scale for backgrounds and borders.

Add this code to your app’s OnStart property. We’ll store everything in a single variable called gblTheme.

powerfxDefine the colour palette
Set(gblTheme, {
brand: {
  primary: ColorValue("#2E86AB"),
  secondary: ColorValue("#A23B72"),
  accent: ColorValue("#F18F01")
},
status: {
  success: ColorValue("#28A745"),
  danger: ColorValue("#DC3545"),
  warning: ColorValue("#FFC107"),
  info: ColorValue("#17A2B8")
},
grayScale: {
  black: ColorValue("#000000"),
  white: ColorValue("#FFFFFF"),
  g100: ColorValue("#F3F2F1"),
  g200: ColorValue("#D2D0CE"),
  g300: ColorValue("#B3B0AD"),
  g400: ColorValue("#8A8886"),
  g500: ColorValue("#484644")
}
});

Once set, any control can use gblTheme.brand.primary instead of a hard‑coded hex code. If the brand color ever changes, you update exactly one line.

Step 2: Choose a Typography Plan

A consistent hierarchy prevents the “headline vs. body” confusion. Pick two font families—one for headings and one for body—and define a set of named sizes.

powerfxAdd typography to the theme
Set(gblTheme, {
// ... keep previous colors ...
typography: {
  headingFont: "'Segoe UI', 'Open Sans', sans-serif",
  bodyFont: "Roboto, 'Helvetica Neue', Arial",
  sizes: {
    xs: 10,
    sm: 12,
    md: 14,
    lg: 18,
    xl: 24,
    xxl: 32
  }
}
});

To apply, set a label’s Font property to gblTheme.typography.headingFont and its Size to gblTheme.typography.sizes.xl.

Step 3: Keep a Set of Icons Handy

Power Apps includes a wide library of built‑in icons, but sometimes you need a custom or brand‑specific symbol. You can store SVG data URIs inside your theme and reuse them across the app.

Here we add three custom icons:

powerfxEmbed SVG icons in the theme
Set(gblTheme, {
// ... keep colors and typography ...
icons: {
  dashboard: "data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M3 13h8V3H3v10zm0 8h8v-6H3v6zm10 0h8V11h-8v10zm0-18v6h8V3h-8z'/%3E%3C/svg%3E",
  customer: "data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z'/%3E%3C/svg%3E",
  settings: "data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58a.49.49 0 0 0 .12-.61l-1.92-3.32a.488.488 0 0 0-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54a.484.484 0 0 0-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.07.62-.07.94s.02.64.07.94l-2.03 1.58a.49.49 0 0 0-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z'/%3E%3C/svg%3E"
}
});

Set an Icon control’s Image property to gblTheme.icons.dashboard and it will render the custom SVG.

Icon size

When using SVG data URIs, the icon color is usually defined inside the SVG. To change the color dynamically you’d need a slightly more complex solution (like a separate SVG for each color or a component that swaps paths). For a simple starter theme, pre‑colored SVGs work well.

Step 4: Apply the Theme to Controls

Now that the theme object holds everything, use it wherever you’d normally type a static value.

ControlPropertyExample Value
ButtonFillgblTheme.brand.primary
ButtonColorgblTheme.grayScale.white
LabelFontgblTheme.typography.headingFont
LabelSizegblTheme.typography.sizes.lg
IconImagegblTheme.icons.customer

If you ever want to change the overall look, you only touch the OnStart block instead of visiting every control.

Security and Performance Considerations

  • No delegation issues: Theme variables are read from the app’s memory; they don’t interact with data sources.
  • App size: Storing many large SVG strings can bloat your app file. Stick to a handful of carefully selected icons; avoid embedding entire icon libraries.
  • Execution order: Ensure Set(gblTheme, …) runs before any control tries to reference it. Placing the code in App.OnStart is the safest approach.

Common Mistakes and Troubleshooting

  • “gblTheme is not recognized” error – The variable hasn’t been set yet. Save, close, and reopen the app to force OnStart to run, or add a Timer that triggers Set(gblTheme,…) on start.
  • Font doesn’t appear on mobile – The custom font family must be available on the device. Stick to web‑safe fonts or use a font embedding technique.
  • SVG icon shows a broken image – Double‑check the data URI syntax. The most common pitfalls are missing ;utf8, or incorrectly URL‑encoded characters. Use a simple SVG first to validate the approach.
  • Inconsistent sizes – Accidentally typing a number instead of referencing gblTheme.typography.sizes.md. Build a habit of using the theme object everywhere.
  • Can’t find the icon I need – Use one of the curated icon libraries (Fluent UI, Font Awesome, Material) and convert the SVG to a data URI. Many online converters exist.

Final Recommendation

Build your theme as early as possible—ideally before you start laying out screens. The small upfront effort of defining gblTheme pays off in maintenance speed and visual consistency. Even if your app is small, you’ll appreciate not hunting for a hex code at the last minute.

References