Change ionic component's background color dynamically [Ionic 4]

I finally resolve my issue.
Basically, migration from ionic 3 to ionic 4 changes rules about css. They are now following angular rules.
.scss components files are not global anymore. With default config, it is now not possible to override child component style.
But, there is two ways to deal with that.

  1. View encapsulation
    https://angular.io/api/core/ViewEncapsulation
    With:
 encapsulation: ViewEncapsulation.None

In that case you will create a component affected and which will be affect others components around him. Be careful with that thougt.
2. Global css
use global.scss of your ionic project to add global css properties which will affect all components of your project.

Finally, when you choose one of both solutions, you can use CSS3 variable:

Something like:

// MAIN COLOR
.primaryColor {
  color: var(--primaryColor);
}
.secondaryColor {
  color: var(--accentColor);
}
.dangerColor {
  color: var(--warnColor);
}

And then in a service in charge of your dynamic style:

        const themeWrapper = document.querySelector('body');
        themeWrapper.style.setProperty('--primaryColor', StyleService.primary.medium);
        themeWrapper.style.setProperty('--primaryLightColor', StyleService.primary.light);
        themeWrapper.style.setProperty('--primaryDarkColor', StyleService.primary.dark);

Et voila, you can now override ionic theme with colors store on server

scss override:


// MAIN COLOR
.primaryColor {
  color: var(--primaryColor);
}
.secondaryColor {
  color: var(--accentColor);
}
.dangerColor {
  color: var(--warnColor);
}

// LIGHT
.lightPrimaryColor {
  color: var(--primaryLightColor);
}
.lightSecondaryColor {
  color: var(--accentLightColor);
}

// DARK
.darkPrimaryColor {
  color: var(--primaryDarkColor);
}
.darkSecondaryColor {
  color: var(--accentDarkColor);
}

.whiteColor {
  color: #ffffff;
}
.blackColor {
  color: #000000;
}
.translucide {
    background-color: rgba(0,0,0,0);
    color: white;
}

// BACKGROUND COLOR
.primaryBackColor {
  background-color: var(--primaryColor);
  color: var(--primaryTextColor);
}
.secondaryBackColor {
  background-color: var(--accentColor);
  color: var(--accentTextColor);
}
// LIGHT
.lightPrimaryBackColor {
  background-color: var(--primaryLightColor);
  color: var(--primaryLightTextColor);
}
.lightSecondaryBackColor {
  background-color: var(--accentLightColor);
  color: var(--accentLightTextColor);
}
// DARK
.darkPrimaryBackColor {
  background-color: var(--primaryDarkColor);
  color: var(--primaryDarkTextColor);
}
.darkSecondaryBackColor {
  background-color: var(--accentDarkColor);
  color: var(--accentDarkTextColor);
}
.dangerBackColor {
  background-color: var(--warnColor);
  color: var(--warnTextColor);
}

// FAB BUTTON
.fab-md-secondary,
.fab-ios-secondary {
  background-color: var(--accentColor);
  color: var(--accentTextColor);
}
.fab-md-primary,
.fab-ios-primary {
  background-color: var(--primaryColor);
  color: var(--primaryTextColor);
}
.fab-md-danger,
.fab-ios-danger {
  background-color: var(--warnColor);
  color: var(--warnTextColor);
}

// BUTTON
.button-md-primary,
.button-ios-primary {
  background-color: var(--primaryColor);
  color: var(--primaryTextColor);
}
.button-md-secondary,
.button-ios-secondary {
  background-color: var(--accentColor);
  color: var(--accentTextColor);
}
.button-md-danger,
.button-ios-danger {
  background-color: var(--warnColor);
  color: var(--warnTextColor);
}

// BUTTON OUTLINED AND CLEAR
.button-outline-md-primary,
.button-outline-ios-primary,
.button-clear-md-primary,
.button-clear-ios-primary {
  background-color: "transparent";
  border-color: var(--primaryColor);
  color: var(--primaryColor);
}
.button-outline-md-secondary,
.button-outline-ios-secondary,
.button-clear-md-secondary,
.button-clear-ios-secondary {
  background-color: "transparent";
  border-color: var(--accentColor);
  color: var(--accentColor);
}
.button-outline-md-danger,
.button-outline-ios-danger,
.button-clear-md-danger,
.button-clear-ios-danger {
  background-color: "transparent";
  border-color: var(--warnColor);
  color: var(--warnColor);
}

and service part


    public setAppTheme(theme?: any, saveTheme?: boolean) {
        const themeWrapper = document.querySelector('body');
        // const themeWrapper = document.getElementById('global-mat-sidenav-container');

        themeWrapper.style.setProperty('--primaryColor', StyleService.primary.medium);
        themeWrapper.style.setProperty('--primaryLightColor', StyleService.primary.light);
        themeWrapper.style.setProperty('--primaryDarkColor', StyleService.primary.dark);
        themeWrapper.style.setProperty('--primaryTextColor', StyleService.primary.textColor);
        themeWrapper.style.setProperty('--primaryLightTextColor', StyleService.primary.lightTextColor);
        themeWrapper.style.setProperty('--primaryDarkTextColor', StyleService.primary.darkTextColor);

        themeWrapper.style.setProperty('--accentColor', StyleService.accent.medium);
        themeWrapper.style.setProperty('--accentLightColor', StyleService.accent.light);
        themeWrapper.style.setProperty('--accentDarkColor', StyleService.accent.dark);
        themeWrapper.style.setProperty('--accentTextColor', StyleService.accent.textColor);
        themeWrapper.style.setProperty('--accentLightTextColor', StyleService.accent.lightTextColor);
        themeWrapper.style.setProperty('--accentDarkTextColor', StyleService.accent.darkTextColor);


        themeWrapper.style.setProperty('--warnColor', StyleService.alert);
        themeWrapper.style.setProperty('--warnTextColor', StyleService.alert.textColor);

        // on previens d'une nouvelle image
        // this.themeImage.next(environment.settings.apiUrl + 'accessible/menu/' + theme.menuImage);

        // if (saveTheme) {
        //     this.localStorageService.setItem(LocalStorageEnum.THEME, theme);
        // }
    }
2 Likes