Styling

Every IC component can be styled directly from MATLAB. The ic.Frame provides a theming system with color tokens that affect all components, while each component exposes a css property (a ic.mixin.StyleBuilder) for instance-level CSS overrides, animations, variables, and layout shortcuts.

Theming

The Frame has a theme() method that sets the color tokens used by all built-in components. These tokens are CSS custom properties (--ic-primary, --ic-border, etc.) defined in ic.style.Theme. Changing a token affects every component in the Frame at once.

Pick colors below and watch the components update in real time. The MATLAB code panel shows the frame.theme() calls you would write:

Light Dark Primary Destructive Secondary Border Background Foreground
65%
frame.theme("primary", ["#0d9488", "#5eead4"]);
frame.theme("destructive", ["#be123c", "#fb7185"]);
frame.theme("secondary", ["#e0f2fe", "#1e3a5f"]);
frame.theme("background", ["#f0fdfa", "#0f172a"]);
frame.theme("foreground", ["#134e4a", "#e2e8f0"]);
frame.theme("border", ["#cbd5e1", "#334155"]);
frame.theme("radius", "8px");

The Frame also has a ColorScheme property that switches between "light" and "dark" mode. Each theme token is actually a pair of values, one per scheme, and the active scheme determines which one is used. Try toggling the dark/light mode on the top-right of the navigation bar: the ColorScheme is synched to it.

When you call frame.theme() with a single value, it applies to the active color scheme only. When you pass a two-element array, the first value sets the light token and the second sets the dark token. You can set multiple tokens in one call, and the naming is flexible: primary, Primary, primary-foreground, primaryForeground, and primary_foreground all resolve to the same token.

frame.theme("primary", ["#e85d04", "#fb923c"]);

frame.theme("border", "#ccc", "muted", "#eee");

The available tokens are: background, foreground, primary, primaryForeground, secondary, secondaryForeground, muted, mutedForeground, accent, accentForeground, destructive, destructiveForeground, success, successForeground, warning, warningForeground, info, infoForeground, border, input, ring, and radius.

Instance styles

The core method is css.style(selector, ...). It takes a CSS selector scoped to the component’s wrapper element, followed by property-value pairs. The selector targets the component’s internal DOM: you are reaching into the frontend template and overriding its CSS. The property names follow MATLAB conventions (camelCase or underscores) and the framework converts them to kebab-case automatically, so border_radius becomes border-radius and backgroundColor becomes background-color.

The demo below shows an ic.Button whose appearance is fully overridden from MATLAB. Change the values in the console or edit the controls to see the result:

Controls
btn = ic.Button("Label", "Styled", "Size", "lg");

btn.css.style("button", ...
    "background", "linear-gradient(135deg, #667eea 0%, #764ba2 100%)", ...
    "color", "#ffffff", ...
    "border_radius", "20px", ...
    "box_shadow", "0 4px 15px rgba(102, 126, 234, 0.4)");

Understanding selectors

The selector string targets elements inside the component’s DOM tree: your styles only affect the specific component instance, never other instances of the same type. If you want to style all instances at once, use global styles (covered below).

btn.css.style("button", "background", "red");

btn.css.style("button:hover", "background", "darkred");

btn.css.style(".ic-btn__label", "fontSize", "18px");

To discover what selectors are available for a given component, use the Developer Tools to inspect the DOM structure of any live instance.

Removing styles

Setting a property to an empty string "" removes it. You can also clear all styles for a given selector, or wipe everything at once:

btn.css.style("button", "background", "red");
btn.css.style("button", "background", "");
btn.css.clearStyle("button");
btn.css.clearStyles();

Convenience methods

The StyleBuilder has shortcut methods for the most common CSS properties, so you do not have to remember CSS property names or deal with pixel strings. Numeric values are automatically converted to pixels.

Type commands in the console below to resize and adjust the slider’s layout properties. Try slider.width = 300px or slider.opacity = 0.5:

Command Window
>>  
slider = ic.Slider();
slider.css.width("200px");
slider.css.height("40px");
slider.css.margin("10px");

Here is the full list of convenience methods grouped by purpose:

Sizing: width, height, minWidth, minHeight, maxWidth, maxHeight. All accept a number (interpreted as pixels) or a CSS string like "50%" or "auto".

Fill shortcuts: fill() sets both width and height to 100%. fillWidth() and fillHeight() set just one axis.

slider.css.fill();

slider.css.fillWidth();
slider.css.fillHeight();

Flex layout: flex(grow, shrink, basis), flexGrow, flexShrink, flexBasis, alignSelf. These control how the component behaves inside a flex container.

panel.css.flex(2, 1, "0px");
panel.css.flexGrow(2);
panel.css.alignSelf("center");

Spacing: margin(value) and padding(value). Accept a number (uniform pixels), a 1-to-4 element numeric array (CSS shorthand), or a CSS string.

Visibility: hide() sets display: none. show(displayType) restores it (defaults to "block"). invisible() and visible() toggle visibility without affecting layout.

comp.css.hide();
comp.css.show("flex");
comp.css.invisible();
comp.css.visible();

Positioning and overflow: position, zIndex, overflow, overflowX, overflowY, opacity.

comp.css.position("absolute");
comp.css.zIndex(10);
comp.css.overflow("hidden");

CSS variables

Some components expose CSS custom properties (variables) that control their appearance without requiring you to know the internal DOM structure. The css.vars() method sets these variables on a given selector. Unlike css.style(), property names are used as-is with no camelCase conversion, and the -- prefix is added automatically if you leave it out.

comp.css.vars("> *", "--my-color", "red", "--my-gap", "12px");

Animations

You can define CSS @keyframes animations from MATLAB and apply them via css.style(). Keyframe stop names like 0% or 50% cannot be used directly as struct field names (MATLAB does not allow fields starting with a digit), so you prefix them with p: p0 becomes 0%, p50 becomes 50%, and so on. The special names from and to work as-is.

Click the button below to see the pulse animation in action:

btn.css.keyframes("pulse", struct( ...
    "from", struct("transform", "scale(1)"), ...
    "p50",  struct("transform", "scale(1.08)"), ...
    "to",   struct("transform", "scale(1)")));

btn.css.style("button", ...
    "animationName", "pulse", ...
    "animationDuration", "0.8s", ...
    "animationIterationCount", "infinite");

To stop the animation and clean up:

btn.css.style("button", "animationName", "");
btn.css.removeKeyframes("pulse");

Keyframe animations are global (not scoped to the component), so any component can reference them by name. This also means you should pick distinctive names to avoid collisions.

Global styles

Instance styles affect a single component. When you want to style every instance of a component type, use the Frame’s globalStyle method instead. This is useful for establishing a consistent look across your application without repeating the same css.style() call on every button or slider you create.

frame.globalStyle("ic.Button", ".ic-btn", ...
    "backgroundColor", "#1a1a2e", ...
    "color", "#e0e0e0");

frame.globalStyle("ic.Button", ".ic-btn:hover", ...
    "backgroundColor", "#16213e");

The selector works the same way as in instance styles, but it applies to all current and future instances of the specified type. The component type is the fully qualified class name, like "ic.Button" or "ic.Slider".

To remove global styles, you have three levels of granularity:

frame.clearGlobalStyle("ic.Button", ".ic-btn");
frame.clearGlobalStyles("ic.Button");
frame.clearAllGlobalStyles();

Browser compatibility

MATLAB renders uifigure components in an embedded browser, but the exact browser engine and version depend on the MATLAB release and the operating system. On macOS, MATLAB bundles its own Chromium Embedded Framework (CEF): R2024b uses Chromium 104, for example. On Windows, some versions rely on the system’s Edge WebView2 instead, which means the available CSS features depend on whatever Chromium version is installed on that machine.

The practical consequence is that you cannot assume a single browser version. If you work on different machines or MATLAB releases, test your custom styles on each one. Features that work reliably across all recent engines: linear-gradient, transforms, transitions, flexbox, CSS grid, and custom properties. Features that may not be available on older engines:

  • CSS nesting (the & parent selector inside a rule block)
  • :has() selector (parent selection based on children)
  • color-mix() and other modern color functions
  • @container queries

When in doubt, check caniuse.com with the Chromium version your MATLAB is using. Use the Developer Tools to inspect how your styles actually render in a live component.