Skip to content

feat(button): sync the md theme with Material Design 2 - #31636

Draft
thetaPC wants to merge 3 commits into
FW-6838-snapshotsfrom
FW-6838-md-sync
Draft

thetaPC wants to merge 3 commits into
FW-6838-snapshotsfrom
FW-6838-md-sync

Conversation

@thetaPC

@thetaPC thetaPC commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Issue number: resolves internal


What is the current behavior?

md buttons use values carried over from v9 instead of Material Design 2: 15.4px padding, 0.06em tracking, a 2px outline in the button's color, a 0.5 fade when disabled, and the same elevation on hover and focus as at rest.

What is the new behavior?

md buttons follow Material Design 2, using the values from Material Components Web 14, Google's MD2 implementation:

  • 16px padding and a 64px min width at the default size, and 0.0893em letter spacing
  • 18px icons with an 8px gap to the label, scaled at the small and large sizes
  • A 1px outline in on-surface at 12%, for colored outline buttons too
  • Elevation 4 on hover and focus for solid buttons
  • Disabled buttons use 38% on-surface text and a 12% container with no elevation, instead of fading the whole button. Material shows disabled elements in a neutral color rather than their own, so a disabled button no longer keeps its color (Material Design 2: disabled state)
  • The pressed ripple is 24% on solid buttons and 12% on outline and clear

To support this, the recipe gains hover.box.shadow, focus.box.shadow and disabled.{color, border.color, box.shadow}. A theme that doesn't set the disabled colors keeps its default colors, so ios and ionic don't change.

Toolbar and datetime buttons keep their current look: no elevation on hover or focus, and disabled toolbar buttons still fade their own colors.

Snapshots are in #.

Does this introduce a breaking change?

  • Yes
  • No

The md button follows Material Design 2 for its spacing, outline, elevation and disabled state. To keep a previous value, set the token for global styles, or the matching --ion-button-* CSS variable for component-specific styles. Replace <fill> with solid, outline or clear, and <size> with small, medium or large.

Property Previous New Token
Padding at the default size 1.1em 16px IonButton.size.medium.padding.start and .end
Min width at the default size none 64px IonButton.size.medium.min.width
Letter spacing 0.06em 0.0893em IonButton.letter.spacing
Icon size 1.35em 1.2857em (18px at the default size) IonButton.size.<size>.icon.font.size
Gap between icon and label 0.3em 0.5714em (8px at the default size) IonButton.size.<size>.icon.leading.margin.end and .trailing.margin.start
Outline border 2px, the button's color 1px, the text color at 12% IonButton.hue.bold.outline.default.border.width and .color (.semantic.default.border.color with a color)
Solid elevation on hover and focus the resting elevation elevation 4 IonButton.hue.bold.solid.hover.box.shadow and .focus.box.shadow
Disabled the whole button at 0.5 opacity 38% text color, a 12% container and no elevation IonButton.hue.bold.<fill>.disabled.opacity, .color, .background and .box.shadow
Pressed ripple 16% 24% on solid, 12% on outline and clear IonButton.hue.bold.<fill>.rippleEffect.opacity

Buttons in toolbars keep their previous colors when disabled and have no elevation on hover or focus.

Other information

Not matched to MD2 on purpose

Known gaps

  • The a11y spec still skips a pressed outline button in md's dark toolbar (TODO(FW-6838)). The lighter ripple raises its contrast from 4.09 to 4.37:1, under WCAG's 4.5:1. The fix belongs to the dark palette

How to test

Check Before After What to look for
Spacing and icons Before After Labels are spaced wider, icons are slightly smaller with more room before the label
Outline and disabled Before After Borders are thin and gray. Disabled buttons are gray instead of faded
Hover and focus Before After Hover over or tab to a solid button: its shadow grows
Toolbars Before After Only the letter spacing changes, and colored outline buttons get the thin gray border

@thetaPC
thetaPC added this pull request to stack #31629 October 22, 2026 22:56
@vercel

vercel Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
ionic-framework Ready Ready Preview Oct 22, 2026 11:07pm UTC

Request Review

This branch was successfully deployed

1 active deployment
Preview — d70ee70f Deployed Oct 22, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

package: core @ionic/core package

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant