ionic-team / ionic-framework

A powerful cross-platform UI toolkit for building native-quality iOS, Android, and Progressive Web Apps with HTML, CSS, and JavaScript.
https://ionicframework.com
MIT License
50.48k stars 13.53k forks source link

bug: After upgrade to Ionic v8 my variables.css are being overwritten by the default values in the core.css file. #29466

Closed VerburgtJimmy closed 3 days ago

VerburgtJimmy commented 1 week ago

Prerequisites

Ionic Framework Version

v8.x

Current Behavior

This happend right after updating ionic from V7 to V8 using the update guide. After creating custom variables like this in my theme/variables.scss:

  /** primary **/
  --ion-color-primary: #00a9b5;
  --ion-color-primary-rgb: 56, 128, 255;
  --ion-color-primary-contrast: #ffffff;
  --ion-color-primary-contrast-rgb: 255, 255, 255;
  --ion-color-primary-shade: #00a9b5;
  --ion-color-primary-tint: #00a9b5;
}

But when I run the app these values will not be used. Instead the values in the core.css file that I import in my global.css like this will be used:

 * App Global CSS
 * ----------------------------------------------------------------------------
 * Put style rules here that you want to apply globally. These styles are for
 * the entire app and not just one component. Additionally, this file can be
 * used as an entry point to import other CSS/Sass files to be included in the
 * output CSS.
 * For more information on global stylesheets, visit the documentation:
 * https://ionicframework.com/docs/layout/global-stylesheets
 */

/* Core CSS required for Ionic components to work properly */
@import "@ionic/angular/css/core.css";

/* Basic CSS for apps built with Ionic */
@import "@ionic/angular/css/normalize.css";
@import "@ionic/angular/css/structure.css";
@import "@ionic/angular/css/typography.css";
@import '@ionic/angular/css/display.css';

/* Optional CSS utils that can be commented out */
@import "@ionic/angular/css/padding.css";
@import "@ionic/angular/css/float-elements.css";
@import "@ionic/angular/css/text-alignment.css";
@import "@ionic/angular/css/text-transformation.css";
@import "@ionic/angular/css/flex-utils.css";

/* Custom */
@import "theme/components/inputs";

My css files are imported like this in my angular.json:

"styles": [
              {
                "input": "src/theme/variables.scss",
                "inject": true
              },
              {
                "input": "src/global.scss",
                "inject": true
              },
              {
                "input": "node_modules/@ionic/angular/css/normalize.css",
                "inject": true
              },
              {
                "input": "node_modules/@ionic/angular/css/structure.css",
                "inject": true
              },
              {
                "input": "node_modules/@ionic/angular/css/typography.css",
                "inject": true
              },
              {
                "input": "node_modules/@ionic/angular/css/core.css",
                "inject": true
              },
              {
                "input": "node_modules/@ionic/angular/css/padding.css",
                "inject": true
              },
              {
                "input": "node_modules/@ionic/angular/css/float-elements.css",
                "inject": true
              },
              {
                "input": "node_modules/@ionic/angular/css/text-alignment.css",
                "inject": true
              },
              {
                "input": "node_modules/@ionic/angular/css/text-transformation.css",
                "inject": true
              },
              {
                "input": "node_modules/@ionic/angular/css/flex-utils.css",
                "inject": true
              },
              {
                "input": "src/theme/variables.css",
                "inject": true
              }
            ],

Expected Behavior

I expect the values of core.css to be overwritten by my values in the variables.scss file and that my app uses the colors that are defined in the variables.scss.

Steps to Reproduce

I don't have a clean install so if not more people with a clean install have this problem than it is a problem focused on my project so it is not possible to reproduce.

Code Reproduction URL

no url

Ionic Info

Ionic:

Ionic CLI : 7.2.0 (/opt/homebrew/lib/node_modules/@ionic/cli) Ionic Framework : @ionic/angular 8.0.1 @angular-devkit/build-angular : 17.3.6 @angular-devkit/schematics : 17.3.6 @angular/cli : 17.3.6 @ionic/angular-toolkit : 11.0.1

Capacitor:

Capacitor CLI : 6.0.0 @capacitor/android : 6.0.0 @capacitor/core : 6.0.0 @capacitor/ios : 6.0.0

Utility:

cordova-res : not installed globally native-run : 2.0.1

System:

NodeJS : v22.1.0 (/opt/homebrew/Cellar/node/22.1.0/bin/node) npm : 10.7.0 OS : MacOs unknown

Additional Information

No response

sean-perkins commented 1 week ago

Hello @VerburgtJimmy if you could provide a minimal reproduction with the same base stylesheets you have described, that would help the team diagnose more.

In v8, we updated the selectors and default variable definitions and recommended that developers move their custom variables stylesheet to be imported/referenced after the primary global styles that import Ionic's global stylesheets.

You have done that with the example snippets you provided, however I would callout a few things:

  1. You are importing the variables stylesheet twice in your angular.json.
  2. You either need to add the stylesheet references for Ionic's global styles in angular.json or import it with a CSS import in a global stylesheet. You do not need to do both, which you are showing in the code snippets provided.

If you can provide more information or a minimal reproduction of variables not being customizable, the team would be happy to assist further.

Thanks!

VerburgtJimmy commented 1 week ago

Thanks for the response.

  1. they are both different files. One is scss and one is css. But the css one is empty. I can remove it just to be sure, but this changes nothing in the app.
  2. What is recommended to do with the global styles? Should I remove them from the global.css or from angular.js. Or doesn't this really matter?

If you can give me some time I will create a new ionic project where I will copy my own config files in there and of course my own css files to see if it also happens in a new project. If this is the case I will drop the link for the public repo here so you can reproduce the issue I am having.

sean-perkins commented 1 week ago

Either approach for global styles is an acceptable pattern in Angular and with Angular libraries, like Ionic Framework. They both result in similar outcomes, however the angular.json enables developers additional customization techniques for bundling: https://angular.io/guide/workspace-config#styles-and-scripts-configuration

Here are two reproduction templates that you can review and experiment with:

  1. Using CSS imports: https://stackblitz.com/edit/angular-dawl1f?file=src%2Ftheme%2Fvariables.css
  2. Use angular.json: https://stackblitz.com/edit/angular-dawl1f-vwkffm?file=angular.json

In both examples the customized primary colors from your provided snippet are applied correctly.

kensodemann commented 1 week ago

Sean already gave you some good examples to go by, but I will just add a few notes here, kind of a free code review based on some things I have noted working with our Enterprise customers as well as maintaining our demos.

  1. Having a src/theme/variables.scss and src/theme/variables.css file is going to cause confusion for other developers on your team or for future you. Since you say the src/theme/variables.css file is empty, I suggest just removing it.
  2. According to the rules of CSS, when all else is equal the last thing specified wins. In your case, you have src/theme/variables.scss specified first in your angular.json, which means anything specified there that is specified in a later file with the same selector will get the value in the later file.
  3. having the Ionic supplied SCSS files specified in the global.scss and then also in the styles array of the angular.json is not only redundant, but makes the final output even harder to reason about.

My suggestions:

  1. reduce your styles specified in the angular.json to the variables and the globals files like this: https://github.com/ionic-enterprise/tutorials-and-demos-ng/blob/main/demos/tea-taster/angular.json#L33
  2. make sure the variables file is last in the list as it is overriding things brought in from the globals file
  3. keep your global files mostly as-is, but perhaps add the appropriate dark theme handling CSS https://github.com/ionic-enterprise/tutorials-and-demos-ng/blob/main/demos/tea-taster/src/global.scss#L28

More on dark mode here: https://ionicframework.com/docs/theming/dark-mode

The other thing I always find helpful for stuff like this is to generate a new app from one of the starters and study the appropriate files.

thetaPC commented 3 days ago

Just wanted to follow up on the issue. Some suggestions were shared to help address the problem. Since there hasn't been a response, I'm assuming everything's sorted out.

Feel free to reopen this if needed or start a new one if anything else comes up.

VerburgtJimmy commented 3 days ago

Yes sorry. The following fixed my issue. My angular.json imported my files like this:

"styles": [
              {
                "input": "src/theme/variables.scss",
                "inject": true
              },
              {
                "input": "src/global.scss",
                "inject": true
              },
              {
                "input": "node_modules/@ionic/angular/css/normalize.css",
                "inject": true
              },
              {
                "input": "node_modules/@ionic/angular/css/structure.css",
                "inject": true
              },
              {
                "input": "node_modules/@ionic/angular/css/typography.css",
                "inject": true
              },
              {
                "input": "node_modules/@ionic/angular/css/core.css",
                "inject": true
              },
              {
                "input": "node_modules/@ionic/angular/css/padding.css",
                "inject": true
              },
              {
                "input": "node_modules/@ionic/angular/css/float-elements.css",
                "inject": true
              },
              {
                "input": "node_modules/@ionic/angular/css/text-alignment.css",
                "inject": true
              },
              {
                "input": "node_modules/@ionic/angular/css/text-transformation.css",
                "inject": true
              },
              {
                "input": "node_modules/@ionic/angular/css/flex-utils.css",
                "inject": true
              },
              {
                "input": "src/theme/variables.css",
                "inject": true
              }
            ],

Changing this to the following fixed my issue:

"styles": [
     "src/global.scss".
     "src/theme/variables.scss"
]