Skip to content

Style System: Improve automated variable fallbacks#94

Merged
ItsJonQ merged 13 commits intomasterfrom
fix/css-variable-fallbacks
Nov 13, 2020
Merged

Style System: Improve automated variable fallbacks#94
ItsJonQ merged 13 commits intomasterfrom
fix/css-variable-fallbacks

Conversation

@ItsJonQ
Copy link
Copy Markdown
Owner

@ItsJonQ ItsJonQ commented Nov 8, 2020

This update fixes the CSS variable fallback handling for IE11.

This solution has been tested and confirmed working in IE11 (via VirtualBox):

Screen Shot 2020-11-08 at 10 16 10 AM

🙈 The Problem

The previous plugin solution relied on an unsupported CSSOM function to retrieve the CSS variable value from :root (more details here).

For example, let's pretend this style exists:

:root {
  --color: red;
}

The previous solution attempted to retrieve the --color value with this:

getComputedStyle(document.documentElement).getPropertyValue('--color')

In IE11, this would result in an empty string ('') because IE11 doesn't understand what --color even is.

🏪 Alternative Root "Store"

Instead of relying on the CSS :root {} object, I replicated the same mechanic by establishing a "virtual" store that exists in JS. When the Style System is created, the initial CSS variables will be used to create and establish this "root store".

When the Stylis plugin goes to work, the parser will be able to retrieve the fallback values from this virtual root store (instead of using CSS :root {}).

🔌 Plugin

The majority of the plugin code was copied over from stylis-plugin-css-variables. Changes were mainly around adding the virtual store for variable fallback resolution.

🤝 Trade offs

This automated solution only supports variables that are:

  1. Designed to live in the :root {} level
  2. initially passed into createStyleSystem

That means locally scoped variables will not be resolved. Also, it (currently) won't resolve variables being defined/modified after the fact.

For the purposes of G2's Component system, I think it's okay if we only support values defined in our variable system. It may encourage users to work with those values, rather than define custom values of their own.

This does affect theming though. The virtual root store won't know how to re-resolve and re-render new theme values that are being pass into <ThemeProvider />.

Perhaps this is okay? At minimum, the UI can render for IE11 (which is great). However, it won't be fully featured compared to other browsers (e.g. theming, night mode, etc...)


🕹 Testing

(The easiest way to test)
Fire up local Storybook and inspect element. If you can see the variable fallbacks, then the system is working 👍 .

Screen Shot 2020-11-08 at 10 36 45 AM

As mentioned above, it's using the virtual "root store" strategy rather than getComputedStyle().getPropertyValue(), which means it will work in IE11.

Note: The CSS variable fallback handling are enabled in develop mode. In production, the plugin only kicks in for IE11.


Resolves #89

@vercel
Copy link
Copy Markdown

vercel bot commented Nov 8, 2020

This pull request is being automatically deployed with Vercel (learn more).
To see the status of your deployment, click below or on the icon next to each commit.

🔍 Inspect: https://vercel.com/itsjonq/g2/dg8ofn0yv
✅ Preview: https://g2-git-fix-css-variable-fallbacks.itsjonq.vercel.app

@ItsJonQ ItsJonQ changed the title Fix/css variable fallbacks Style System: Improve automated variable fallbacks Nov 9, 2020
@ItsJonQ ItsJonQ marked this pull request as ready for review November 9, 2020 21:08
Copy link
Copy Markdown
Collaborator

@sarayourfriend sarayourfriend left a comment

Choose a reason for hiding this comment

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

LGTM and seems to work great. Left some nits and tips for types and some questions about the approach but otherwise 👍

Comment on lines +4 to +7
/**
* Stores CSS config variables that are expected to be added to :root.
* This is used for CSS variable fallback handling for IE 11.
*/
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Type correction: state is probably better typed as Record<string, string> rather than a plain object type. That should be corrected throughout and you can alias it using @typedef {Record<string, string>} State if you'd like (probably for the best).

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

@saramarcondes I apologize... I don't know how to do this 🙈.

* Interprets and retrieves the CSS fallback value of a declaration rule.
*
* @param {string} declaration A CSS declaration rule to parse.
* @param {object} rootStore A store for CSS root variables.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This can be typed as RootStore by importing it @param {import('./createRootStore').RootStore}

Suggested change
* @param {object} rootStore A store for CSS root variables.
* @param {import('./createRootStore').RootStore} rootStore A store for CSS root variables.

* variables.
*
* @param {string} content Stylis content to parse.
* @param {object} rootStore A store for CSS root variables.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Same here.

Jon Q and others added 2 commits November 12, 2020 10:39
Jon Q and others added 3 commits November 12, 2020 10:42
@ItsJonQ
Copy link
Copy Markdown
Owner Author

ItsJonQ commented Nov 12, 2020

@saramarcondes I pushed my fixes for the items you suggested (thank you!).
I'm not sure how to go about the typing stuff though 😊

Copy link
Copy Markdown
Collaborator

@sarayourfriend sarayourfriend left a comment

Choose a reason for hiding this comment

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

🚀 We can fix the types when we work on the whole of the create-styles package 👍

@ItsJonQ ItsJonQ merged commit 16ada8e into master Nov 13, 2020
@ItsJonQ ItsJonQ deleted the fix/css-variable-fallbacks branch December 10, 2020 20:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Styles: Ensure (automatic) variable fallbacks can render

2 participants