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

Emotion: Provider to increase className specificity #18483

Open
ItsJonQ opened this issue Nov 13, 2019 · 5 comments
Open

Emotion: Provider to increase className specificity #18483

ItsJonQ opened this issue Nov 13, 2019 · 5 comments
Assignees
Labels
[Package] Components /packages/components [Type] Enhancement A suggestion for improvement.

Comments

@ItsJonQ
Copy link

ItsJonQ commented Nov 13, 2019

👋Hallo!

This is a follow-up to the recently merged #17963 PR where we introduce CSS-in-JS into @wordpress/components via Emotion.

Use case

The use case for this would be if we wanted to implement emotion React components into an older applications, with hostile pre-existing CSS rules (that probably won't/can't go away soon).

Example:

<ScopeProvider scope='html body'>
  ...
  <Thing />
  ...
</ScopeProvider>

Instead of rendering the standard .css-lkj1d9 class, it would render html body .css-lkj1d9.

To combat things like legacy based #id CSS class names, something I did was add (or find) an #id on html, and scope it like html#some-id body.

This resolved all integration based CSS specificity issues for me :).

Example/Solution

This was around the time Emotion v10 was being created. @mitchellhamilton created an example of this working with Emotion V10.

Here's the Codesandbox:
https://codesandbox.io/s/scopeprovider-and-frameprovider-qk1kg

I recently forked it, updated dependencies, and added comments.

@ItsJonQ ItsJonQ added the [Package] Components /packages/components label Nov 13, 2019
@ItsJonQ ItsJonQ self-assigned this Nov 13, 2019
@ItsJonQ
Copy link
Author

ItsJonQ commented Nov 13, 2019

Update!~ Will use __experimental to the component name, for safety :)

@youknowriad
Copy link
Contributor

Where do you see a need for this in our context?

@ItsJonQ
Copy link
Author

ItsJonQ commented Nov 13, 2019

@youknowriad Sure thing!

For example, the input (aka. TextControl) component from @wordpress/components.

Taking a look at Gutenberg within WP Admin, specifically in the sidebar.

In order to override the default wp-admin styles of:

input[type="text"],
...
textarea {
  ...
}

The styles need to increase specificity to override (or reset), like this:

.edit-post-header .input-control,
.edit-post-header input[type="text"],
... {
  ...
}

Components (in this case input) rendering within .edit-post-header, will have their styles sanitized/adjusted.

Where this is tricky is:

a. When the TextControl component is refactored with CSS-in-JS (Emotion)
b. A Portal'ed component is rendered outside of .edit-post-header (or some other form of style scoping)


Emotion will generate a className like .css-dsjld1f. The existing input[type="text"] will override that, due to its increased specificity.

Wrapping the Gutenberg app with <ScopeProvider scope='html'>, will ensure that any Emotion rendered className will be stronger than existing (wp-admin) ones.

(Note: I always use html as the example, because it's a selector that will 100% always be there. You can prefix the generated classNames with anything)

Also, regardless of its React/DOM location, the Provider's scope (e.g. html) will be prefixed to the rendered className.

Hopefully this explanation helps!

@youknowriad
Copy link
Contributor

Thanks that is a good example and explanation.

Now, say we are using a CSS-in-JS versioin of TextControl inside a component in block-editor that is not written in CSS-in-JS (say PostTitle just a random example) and I want to tweak the style of the TextControl inside that PostTitle specifically (I know we do these kind of things a lot in Gutenberg). Wouldn't this change make it harder to achieve?

@ItsJonQ
Copy link
Author

ItsJonQ commented Nov 13, 2019

@youknowriad That's a great question!

Had to really think about this. Even chatted about it with @diegohaz!

In the case of PostTitle, the current styles...

.editor-styles-wrapper .editor-post-title__block .editor-post-title__input

That would be stronger than the (scoped) generated Emotion styles of:

html .css-djajwkda

Due to the extra selectors, so we should be safe for the current implementation 👍


That being said, it's not 100% full-proof either.

In certain scenarios, what if somehow your current older styles (below) is not stronger?

.editor-styles-wrapper .editor-post-title__input

In that case, you may have to adjust the old/non CSS-in-JS styles a bit.

In these cases, you'll have to adjust something either from the Emotion side, or the non emotion side. Having ScopeProvider gives your CSS-in-JS components the ability to be adjusted.

ScopeProvider provides your CSS-in-JS Emotion rendered styles with the same abilities of increasing specificity of styles - a method gaining back control. Having the same powers to fight work with older CSS.

@github-actions github-actions bot added the [Status] In Progress Tracking issues with work in progress label Jun 16, 2020
@skorasaurus skorasaurus removed the [Status] In Progress Tracking issues with work in progress label Jan 20, 2023
@jordesign jordesign added the [Type] Enhancement A suggestion for improvement. label Aug 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Package] Components /packages/components [Type] Enhancement A suggestion for improvement.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants