Skip to content

Conversation

@thetaPC
Copy link
Contributor

@thetaPC thetaPC commented Nov 19, 2025

Issue number: internal


What is the current behavior?

Themes are still using the stepped color variables.

What is the new behavior?

The CSS variable --ion-background-color-step-{number} is no longer recommended for use and has been replaced by a more intuitive and standardized naming convention as part of Ionic's new theming structure. The functionality provided by the old variable has been replaced with a new set of CSS variables that use the same color values but are named: --ion-color-gray-{number}.

This new structure aligns with how other popular design systems and frameworks are setting up their color palettes (e.g., using names like gray, red, blue, followed by a number to denote the shade). Additionally, it follows the proposal agreed upon within the design doc.

  • Added gray tokens based on themes and palettes
  • Replaced background stepped color variables with gray tokens

The CSS variable --ion-text-color-step-* is being replaced by --ion-color-text-* to adhere to the standardized naming convention for Ionic's new theming structure (--ion-color-*-*). This change aims for greater clarity and consistency within the framework's color palette.

  • Added text tokens based on themes and palettes
  • Replaced text stepped color variables with text tokens

The original thought was to use only the --ion-color-gray-* variables for all purposes (backgrounds, text, icons, etc.). However, it was quickly determined that text color requirements are not a 1:1 match with the gray steps designed for backgrounds and other elements. Text often requires a different shade to maintain proper contrast and readability across various theme palettes (especially between high contrast and high contrast dark modes). Introducing the dedicated functional variable --ion-color-text-* solves this issue by allowing text color to be defined independently based on the current palette's needs.

Does this introduce a breaking change?

  • Yes
  • No

You simply need to swap the text of the background stepped variables with the gray variables. The number suffix remains exactly the same:

Old Variable (Deprecated) New Variable
--ion-background-color-step-50 --ion-color-gray-50
--ion-background-color-step-900 --ion-background-color-step-900

Unlike the migration for background colors, the number suffix for text colors is not a direct swap. Due to the inverse nature required for contrast, the new text variable number is calculated by subtracting the old number from 1000.

Old Variable (Deprecated) Calculation New Variable
--ion-text-color-step-50 1000−50 --ion-color-text-950
--ion-text-color-step-900 1000-900 --ion-color-text-100

Other information

@vercel
Copy link

vercel bot commented Nov 19, 2025

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

Project Deployment Preview Comments Updated (UTC)
ionic-framework Ready Ready Preview Comment Dec 6, 2025 2:38am

@github-actions github-actions bot added the package: core @ionic/core package label Nov 19, 2025
// TODO: ADD TYPE
export const darkPrimitiveColors = {
// TODO: Update hex values to use the text color variable and background color variable
gray: generateColorSteps('#ffffff', '#000', true),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I decided to use white and black for the base because base should be as simple as possible.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created this file so these colors can be exported to iOS since iOS uses the same gray colors. I didn't think we needed duplicate code (one for base and one for iOS) when the colors are the same.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The difference is the text color. The previous version had a dark gray but if you compare it to ionic-modular then the old screenshot is actually wrong. The correct text color is #000 (again based on ionic-modular) and that's what the updated screenshot is showing. I don't know why it didn't trigger an issue in ionic-modular but I suspect that it's due to the set-content file finally using the new theming structure. Regardless, I need this to pass checks.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The difference is the text color. The previous version had a dark gray but if you compare it to ionic-modular then the old screenshot is actually wrong. The correct text color is #000 (again based on ionic-modular) and that's what the updated screenshot is showing. I don't know why it didn't trigger an issue in ionic-modular but I suspect that it's due to the set-content file finally using the new theming structure. Regardless, I need this to pass checks.

Copy link
Contributor Author

@thetaPC thetaPC Dec 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The difference is the border. The previous version didn't quite show the border and the tests were trying to complain that the border was gone. I ended up giving it a container padding so we don't lose the border. I'm not sure why this test failing prior but I suspect that it's due to the set-content file finally using the new theming structure. Regardless, I need this to pass checks. It was only failing for iOS since it's the only one with a border top.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The difference is the activated button bg. The previous version had a lighter blue but if you compare it to ionic-modular then the old screenshot is actually wrong. The correct color is #e9ecfc (again based on ionic-modular) and that's what the updated screenshot is showing. I don't know why it didn't trigger an issue in ionic-modular but I suspect that it's due to the set-content file finally using the new theming structure. Regardless, I need this to pass checks.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The difference is the border. The previous version didn't quite show the border and the tests were trying to complain that the border was gone. I ended up giving it a container padding so we don't lose the border. I'm not sure why this test failing prior but I suspect that it's due to the set-content file finally using the new theming structure. Regardless, I need this to pass checks. It was only failing for iOS since it's the only one with a border top.

fontFamily: '-apple-system, BlinkMacSystemFont, "Helvetica Neue", "Roboto", sans-serif',

color: {
'overlay-bg': 'var(--ion-overlay-background-color, var(--ion-color-gray-100))', // Available only in iOS
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created a functional color overlay-bg because it is being used by multiple components. It didn't make sense to create a new variable per component. However, I'm not opposed to making it per component.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

package: angular @ionic/angular package package: core @ionic/core package package: react @ionic/react package

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants