Why M3 Svelte has on on primary

The rest of this post speaks in terms of dark mode.

Normally in Material 3, primary is light, on primary is the opposite, primary container is dark, and on primary container is the opposite. So Material 3 decided to make the checkmark in its checked switch have a background of on primary and a color of on primary container . What could possibly go wrong?

Well it turns out that in some themes, primary container is not dark. Instead of primary container and on primary container (normal), you might have primary container and on primary container (vibrant), or primary container and on primary container (monochrome), or even primary container and on primary container (high contrast). So when you use on primary container as the foreground against on primary , this makes the icon literally invisible or at least ugly.

Invisible checkmark in M3 Svelte

Invisible checkmark in M3 Svelte

Invisible checkmark in Android's implementation

Invisible checkmark in Android's implementation

M3 Svelte solves this with a custom color called on on primary, defined like this:

const onOnPrimary = DynamicColor.fromPalette({
  name: "on_on_primary",
  palette: (s) => s.primaryPalette,
  background: () => materialColors.onPrimary(),
  contrastCurve: () => new ContrastCurve(6, 6, 7, 11),
});
More posts