Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support theming with CSS Custom Properties #4352

Open
SanderElias opened this issue May 2, 2017 · 72 comments
Open

Support theming with CSS Custom Properties #4352

SanderElias opened this issue May 2, 2017 · 72 comments
Labels
area: theming blocked This issue is blocked by some external factor, such as a prerequisite PR feature This issue represents a new feature or feature request rather than a bug or bug fix needs: discussion Further discussion with the team is needed before proceeding P4 A relatively minor issue that is not relevant to core functions

Comments

@SanderElias
Copy link

SanderElias commented May 2, 2017

feature request

Use CSS custom properties for at least color selection.

What is the expected behaviour?

To be able to alter the color-scheme during runtime on supported browsers, and fall-back to predefined SASS defined colors on others

Here is a sample (by Cris Coyier) of how CSS custom properties might work

Is there anything else we should know?

Here is a simple sass mixin that might help:

@mixin variable($property, $variable, $fallback) {
  #{$property}: $fallback;
  #{$property}: var($variable);
}

By using something like that mixin, support for browsers that have no CSS variables support, stay's the same way as its now, while supported browsers gain a way more flexible way to use colors.

@jelbourn jelbourn added the feature This issue represents a new feature or feature request rather than a bug or bug fix label May 2, 2017
@jelbourn
Copy link
Member

jelbourn commented May 2, 2017

We do actually plan on doing this eventually but don't have it as scheduled work at the moment.

@SanderElias
Copy link
Author

TIL about PostCSS. I taught I would share it here. The reason for that is that it enables to use standard CSS (Including custom CSS properties!), and then compile it down for old browsers. This is a huge win over sass, as you need to compile that for old and new browsers alike.
This is the plugin(cssnext) that makes this possible.
Among other nice to have things.

@angular angular deleted a comment from listepo-alterpost Oct 12, 2017
@joshuakwaite
Copy link

Is there a timeline on this yet?

@jelbourn
Copy link
Member

It will likely be early 2020 (when Microsoft plans to end support for IE11)

@LayZeeDK
Copy link
Contributor

It will likely be early 2020 (when Microsoft plans to end support for IE11)

How about an opt-in option to consume CSS Custom Properties for those of us lucky enough to ditch Internet Explorer 11?

@babeal
Copy link

babeal commented May 9, 2018

someone seemed to solve it with css variables and IE 11 fallback. https://github.com/datorama/themify

@arjunyel
Copy link

StencilJS, created by the Ionic team, has a conditionally loaded CSS variable polyfill, if the Angular Material team talks with them and includes the polyfill Material would be able to switch to CSS Variables. Thank you for your time, have a great day!

@arjunyel
Copy link

Here is a CSS Properties ponyfill https://github.com/jhildenbiddle/css-vars-ponyfill

@Rodrigo54
Copy link

I believe that this functionality would bring enormous benefits to the creation of themes for the material, since with native variables you will not have to load files with css of themes as the documentation itself does. That brings more perfomance.

@darkbasic
Copy link

I really don't understand why they don't simply use the polyfill and just switch to css variables now. This is GREAT downside right now.

esotrope added a commit to esotrope/material2 that referenced this issue Sep 15, 2018
Before, the material font-family could only be set at application build-time. Now, developers can modify the material font-family at runtime by setting the --mat-font-family css variable. This will greatly improve the application's ability to be themed dynamically at runtime and with WYSIWYG material theme editors.

This commit partially addresses this feature request: angular#4352
esotrope added a commit to esotrope/material2 that referenced this issue Sep 16, 2018
Before, the material font-family could only be set at application build-time. Now, developers can modify the material font-family at runtime by setting the --mat-font-family css variable. This will greatly improve the application's ability to be themed dynamically at runtime and with WYSIWYG material theme editors.

This commit partially addresses this feature request: angular#4352
esotrope added a commit to esotrope/material2 that referenced this issue Sep 16, 2018
Before, the material font-family could only be set at application build-time. Now, developers can modify the material font-family at runtime by setting the --mat-font-family css variable. This will greatly improve the application's ability to be themed dynamically at runtime and with WYSIWYG material theme editors.

This commit partially addresses this feature request: angular#4352
esotrope added a commit to esotrope/material2 that referenced this issue Sep 16, 2018
Before, the material font-family could only be set at application build-time. Now, developers can modify the material font-family at runtime by setting the --mat-font-family css variable. This will greatly improve the application's ability to be themed dynamically at runtime and with WYSIWYG material theme editors.

This commit partially addresses this feature request: angular#4352
@vasicvuk
Copy link

vasicvuk commented Oct 19, 2018

I agree that this is huge downside to not use CSS variables.

Anyway it should be nice to at least remove all fade-out and other SASS functions dependent on Color so at least colors can be defined as CSS variables as a start. This will allow people to use CSS variables in theme definition and not change how theming works now.

@darkbasic
Copy link

We have customers who want to switch to Ionic 4 just because of CSS variables: this is starting to be a serious issue for those who want to achieve a modern and pleasant to work with custom theming.

@manklu
Copy link

manklu commented Oct 21, 2018

@jelbourn

It will likely be early 2020 (when Microsoft plans to end support for IE11)

Where did you get this date from? EOL of Windows 8.1 is 2023. https://support.microsoft.com/en-gb/help/13853/windows-lifecycle-fact-sheet

IMHO there are only two parts necessary

  1. A style sheet with custom properties
  2. For older browsers a script that replaces the property references with fixed values. Simple text replace should be enough.

@darkbasic

This comment has been minimized.

@manklu
Copy link

manklu commented Oct 21, 2018

@darkbasic

You can use IE11 in Windows 10 as well, so that means October 14, 2025 AT LEAST.

If you also count Windows 10, the Enterprise LTSC support is currently running until 2028 😉 But there you have Edge as an alternative making it a lesser problem.

@darkbasic
Copy link

Nobody prevents you from installing Chrome on Windows 8 as well ;)

@vasicvuk
Copy link

@darkbasic Edge is an default browser for Windows 10 so defiantly IE11 is not an issue on Windows 10. You will use Edge or install Chrome when using Windows 10.

@manklu This stylesheet can be user defined so that user can decide to use CSS variables or not. But in order for this to happen functions over colors like: fade-out, darken, lighten must be removed from SASS code in order for project to compile.

@manklu
Copy link

manklu commented Oct 22, 2018

@darkbasic Corporate policies may prohibit that.

@vasicvuk I know that this is a big bunch of work. But i don't think it's necessary to maintain two separate sets of style sheets.

@jelbourn
Copy link
Member

jelbourn commented Oct 22, 2018

Jan. 2020 is end-of-life for Windows 7, which is the most recent major Windows OS version on which Edge can't be installed.

@darkbasic

This comment has been minimized.

@jelbourn
Copy link
Member

@darkbasic Please keep your language professional.

@vasicvuk
Copy link

vasicvuk commented Oct 22, 2018

@jelbourn In 2020 there will be something new probably better then CSS variables that we have now, so there is no point in waiting for technology that is already here.

I agree with @darkbasic. For browsers without updates polyfill should be used.

@manklu
Copy link

manklu commented Oct 22, 2018

@jelbourn

According to Microsofts FAQ, Edge can't be installed on Windows 8.1
https://docs.microsoft.com/en-us/microsoft-edge/deploy/microsoft-edge-faq

Q: Will Windows 7 or Windows 8.1 users get Microsoft Edge or the new Microsoft EdgeHTML rendering engine?

A: No. Microsoft Edge has been designed and built to showcase Windows 10 features like Cortana, and is built on top of the Universal Windows Platform.

@darkbasic
Copy link

we don't want to require apps to Polyfill CSS variables, since the polyfills are imperfect

May I ask you to clarify the meaning of "imperfect" in this context?
Because on one hand we have "imperfect" IE11 support (which almost nobody uses), dry code and an awesome developer experience, while on the other hand we have "perfect" IE11 support but also tons of redundant CSS and a high negative impact on the developer experience.
If it was me I wouldn't hesitate to choose the first path, even if it means delegating IE11 to its own legacy bundle stuffed with polyfills.

@smnbbrv
Copy link

smnbbrv commented Apr 29, 2020

Would it be an option to maintain two parallel versions of sass file? One w/ and one w/o css variables? This is the approach jQuery came to when they made v2 many years ago. They succeeded with that quite well and btw won a lot of performance by cutting off old browsers.

So, this would solve this particular issue and potentially would give performance benefits to the modern browsers because of smaller CSS bundles and simply better approaches.

Yes, more work to be done and more tests to be written. But this is a price for ie11. Still I hope it is possible to have the common sass codebase meanwhile.

@darkbasic
Copy link

It looks like everyone is dropping IE11

IMG_20200516_092523

@jpike88
Copy link

jpike88 commented May 16, 2020

I'm for whatever needs to be done ALSO providing a pathway for ensuring IE11 still functions correctly.

I respect (and envy) LinkedIn's announcement that IE11 support is being left behind, but that's a decision they make as a product, not as a framework which countless products across a range of use cases depend on.

P.S If you're mad at the fact that in 2020, IE11 is still being used in many large companies around the world, be mad at the reality that old and slow change management process are common in larger organizations, not at the employees who deserve the best experience that product creators can provide. But to think IE11 isn't important anymore because it has a small market share would be to discount the reality that enterprise SaSS providers have to deal with. Nobody should be left behind :)

@SanderElias
Copy link
Author

@jpike88 By stills supporting IE11 we (the total developer community) are enabling/allowing a known insecure browser to still exists.
While I do get the leave none behind sentiment, I strongly believe that this is allowing bad practices to pertain. It is not a service to end-users.
Heck, Linked-In is part of Microsoft, and they drop support. That should be telling.

@nuxodin
Copy link

nuxodin commented Jun 16, 2020

Has anyone tried my polyfill?
https://github.com/nuxodin/ie11CustomProperties

@wawyed
Copy link

wawyed commented Mar 24, 2021

Could we have an update on this? It's been more than 6 months since the last update.

@LayZeeDK
Copy link
Contributor

  • Angular version 12 deprecates (not removes) support for Internet Explorer 11. This is the last browser officially supported by Angular which doesn't support CSS Custom Properties.
  • Angular Material is migrating to MDC Web internally. MDC Web uses CSS Custom Properties.

@Dunos
Copy link

Dunos commented Mar 24, 2021

  • Angular version 12 deprecates (not removes) support for Internet Explorer 11. This is the last browser officially supported by Angular which doesn't support CSS Custom Properties.
  • Angular Material is migrating to MDC Web internally. MDC Web uses CSS Custom Properties.

So when can we expect that migration, in Angular 12 or Angular 13+?

@LayZeeDK
Copy link
Contributor

I don't know. It's been ongoing for years.

@jelbourn
Copy link
Member

We do indeed plan on deprecating support for IE11 in Angular v12. It's still to be determined in which version we'll fully drop IE11 support, but that would be the prereq for us moving to a CSS variable based theming system.

The switch over the using MDC Web under the hood is going to make this much easier for us at that point, but I don't have an ETA. We're actively rolling out the new versions to teams inside Google and using their feedback to fix bugs and make improvements before we lock into a stable API on npm.

@LayZeeDK
Copy link
Contributor

LayZeeDK commented Mar 25, 2021

Thanks for confirming, @jelbourn.

Do the MDC-based variants in Angular Material Experimental have feature parity? Are you looking for external feedback or contributions?

@jelbourn
Copy link
Member

The MDC-based components in experimental should have feature parity with the existing components. Except for chips, they should all also be API compatible (i.e., the exact same APIs). The caveats are:

  • List is not done because MDC just rewrote it recently
  • MDC also rewrote their chips recently and we need to update ours
  • Our mdc-based slider is in progress (but it will have range support)
  • Toggle buttons are planned by MDC but haven't been finished yet

We're happy to get any feedback, though we haven't put out any public docs yet on adopting the new versions, so there might be some bumps in that regard. When we do eventually move them into stable, there will be automated tooling to assist (which we've been using and refining inside Google so far).

@LayZeeDK
Copy link
Contributor

@jelbourn
That sounds great. Thanks for the update, looking forward to see how this comes together 🙌 I think CSS Custom Properties will make a lot of issues go away. Interesting to see which future this opens up for Angular Components.

@csvn
Copy link
Contributor

csvn commented Aug 5, 2021

We do indeed plan on deprecating support for IE11 in Angular v12. It's still to be determined in which version we'll fully drop IE11 support, but that would be the prereq for us moving to a CSS variable based theming system.

According to the Angular v12 relase post, IE11 will be dropped in v13. I guess that makes it possible to move forward with this issue. Though I guess it still takes some thought with the effort to rewrite the components to use MDC.

@jelbourn
Copy link
Member

jelbourn commented Aug 6, 2021

Yeah, we're formally dropping IE11 in v13. Updating our theming system to use CSS variables is near the top of my list of things to focus on next. One thing we're waiting on, though, is for MDC to finish updating their own theming APIs to better align with ours. You can see an example of this in #23143, which covers the slide-toggle

@RobinBomkampDv
Copy link

Hey @jelbourn,
any updates on this issue? :)

@wawyed
Copy link

wawyed commented Jul 26, 2022

I was wondering if there are any updates on this?

@LayZeeDK
Copy link
Contributor

Looks like Angular Material transitions to MDC-based components in Angular Material version 15: https://github.com/angular/components/pulls?q=is%3Apr+sort%3Aupdated-desc+%22use+mdc%22

@suchar-intens
Copy link

We migrated our project to Angular Material 15, but it seems MDC-based componets doesn't solve the problem. We have exactly two issues that block us from defining the primary, accent and warn colors as CSS variables.

mat.define-palette(( 
  ...
  500: var(--primary-color-500),
  ...
))

The first issue is in _progress-bar-theme.scss on the line 16:

track-color: color.adjust(mdc-theme-color.prop-value($color), $alpha: -0.75),

Calling the function color.adjust causes this error:
SassError: $color: var(--primary-color-500) is not a color.

The second issue is in _mdc-helpers.scss inside the mixin using-mdc-theme:

mdc-theme-color.$on-primary:
      if(mdc-theme-color.contrast-tone(mdc-theme-color.$primary) == 'dark', #000, #fff);

Calling the function mdc-theme-color.contrast-tone causes this warning:
var(--primary-color-500) is not a color. Falling back to "dark" tone.

Without these two issues, the colors defined as CSS properties would work fine.

@LayZeeDK
Copy link
Contributor

LayZeeDK commented Dec 8, 2022

@suchar-intens, yes this is tracked in #25981

@RobinBomkamp
Copy link

Hey @jelbourn / @crisbeto ,
any updates on this issue? :)

@richardsengers
Copy link

Any news would be very appreciated!

@purrfectdoodle
Copy link

Any news on this?

@probert94
Copy link

In a new project, I tried to use CSS custom properteis to theme my own components. I never really liked theming my own components using SCSS because:

  • I need an additional file and cannot use the *.component.scss file.
  • I need to import this file in my global theming file and call the tehming mixin. The paths there could become quite deep depending on the complexity of the app.
  • The styles in the theming file are not scoped to the component by default, so I have to use a specific selector.
  • When using multiple themes that can be switched at runtime, all component themes have to be compiled for all defined themes resulting in a lot more css code and therefore bigger bundles. I know there are workarounds for this issue but this makes the already complex theming even more complex.

What I now did is to define all available theming properties as css properties under html selector.
Example:

html {
  --mat-primary-default: mat.get-theme-color($theme, primary, default);
  --mat-primary-text: mat.get-theme-color($theme, primary, text);
}

Defining an additional dark theme looks like this:

body.dark {
  --mat-primary-default: mat.get-theme-color($dark-theme, primary, default);
  --mat-primary-text: mat.get-theme-color($dark-theme, primary, text);
}

This way you can simply use it in your *.component.css file like this:

:host {
  color: var(--mat-primary-text);
}

In my opinion this is a lot simpler and will hopefully become the default for theming your own components.
Is there any downside to this approach that I am missing?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: theming blocked This issue is blocked by some external factor, such as a prerequisite PR feature This issue represents a new feature or feature request rather than a bug or bug fix needs: discussion Further discussion with the team is needed before proceeding P4 A relatively minor issue that is not relevant to core functions
Projects
None yet
Development

No branches or pull requests