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

Use :where to reduce specificity #203

Merged
merged 5 commits into from
Sep 29, 2021
Merged

Use :where to reduce specificity #203

merged 5 commits into from
Sep 29, 2021

Conversation

adamwathan
Copy link
Member

@adamwathan adamwathan commented Sep 24, 2021

This PR changes the output of this plugin to use the :where pseudo-class to reduce the specificity of the selectors, making it possible to easily override typography styles with utilities.

Here's an example of how the output has changed:

- .prose a code {
+ .prose :where(a code) {
    color: #111827;
  }

Prior to this PR, using a utility like this to override a typography style like this wouldn't work unless you enabled the important option in your tailwind.config.js file:

<div class="prose">
  <!-- ... -->
  <p>
    The <a href="#"><code class="text-green-500">:where pseudo-class</code></a> is awesome.
  </p>
</div>

After merging this PR, the code above will just work 🥳 This solves one of the most common pain points of working with this plugin, as people often want to make minor tweaks within a typographic block and out of the box they can't.

This CSS feature has great browser support these days, but it doesn't work in Safari < 14:

https://caniuse.com/mdn-css_selectors_where

Safari 15 was just released, so I expect to see Safari 13 quickly become something we don't have to worry about and I'm not too worried about this change. We could introduce an option to preserve the old behavior if needed, would be really easy.

This is technically a breaking change, so will target the next version of the plugin.

src/index.js Outdated
@@ -44,6 +48,8 @@ module.exports = plugin.withOptions(
...Object.keys(config).filter((modifier) => !DEFAULT_MODIFIERS.includes(modifier)),
])

console.log(configToCss(config['DEFAULT']))

Choose a reason for hiding this comment

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

Remove?

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks fixed!

@neupauer
Copy link
Contributor

neupauer commented Sep 25, 2021

Hey, great idea 🥳. One issue I noticed is that pseudo elements like ::before should be after the :where parenthesis.

- `:where(ul > li::before)`
+ `:where(ul > li)::before`

@adamwathan
Copy link
Member Author

@neupauer Ah good catch, I forgot about this! I'll make sure to get that fixed before merging 👍🏻

@neupauer
Copy link
Contributor

Idea 💡

Hey, I probably shouldn't put this in this PR :)

I got an idea how to make a .no-prose utility that disables styles inside .prose container.

<div class="prose">
  <!-- Styled -->
  <div class="no-prose">
    <!-- NOT Styled -->
  </div>
  <!-- Styled -->
</div>
.prose :where(_SELECTOR_):not(:where(.no-prose _SELECTOR_))

Proof of concept here: https://play.tailwindcss.com/V4LPQ3jV46?file=css - it seems to work quite well

I'll try to find if there are any edge cases where it won't work, and also I don't know yet how it affects the specificity.

This is a fairly naive solution and could/should be made more robust to handle other pseudo-elements like ::first-letter, ::first-line, etc. but I'm inclined to just roll with this until someone actually opens an issue because they needed support for those.
@adamwathan
Copy link
Member Author

@neupauer Let's chat about that here!

#32 (comment)

@adamwathan
Copy link
Member Author

Just noticed another bug in the current output (damn you snapshot tests)...

image

Will have to fix that before merging (super fixable).

@adamwathan
Copy link
Member Author

Need to also check how this behaves with the prefix option, not sure if postcss selector parser handles the inside of where.

@reinink
Copy link
Member

reinink commented Sep 29, 2021

I've updated this plugin to have a new target option, which allows you to enable/disable the use of the :where() selectors. The options include:

target: 'modern' // enables :where() selectors (the default)
target: 'legacy' // disables :where() selectors

@reinink reinink merged commit 8678309 into master Sep 29, 2021
@reinink reinink deleted the use-where branch September 29, 2021 15:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants