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

in 3.3 @apply dark: doesn't work anymore with vue :deep(.child-class) #11024

Closed
remiconnesson opened this issue Apr 17, 2023 · 7 comments
Closed
Assignees

Comments

@remiconnesson
Copy link

What version of Tailwind CSS are you using?
v3.3.1

What build tool (or framework if it abstracts the build tool) are you using?
vite4 and vite3 (happened with both)

What version of Node.js are you using?
v19.1.0

What browser are you using?
Chrome

What operating system are you using?
WSL2 ubuntu 22

Reproduction URL
https://github.com/remiconnesson/tailwind-vue-deep-apply-dark-bug

Describe your issue
hello,

tailwincss is set in darkMode: "class" and we are using useDark from vueUse to add and remove the dark class.

in App.vue we have a child component

<template>
  [ ... ]
  <div class="wrapper">
    <ChildText />
  </div>
  [ ... ]
</template>

<style scoped>
[...]
.wrapper :deep(.child-text) {
  @apply text-pink-700 dark:text-yellow-300;
}
[...]
</style>

targeting @/components/ChildText.vue

<template>
  <div class="child-text text-xl mt-8">
    I am targeted by my parent component with
  </div>
  [...]
</template>

but the dark: modifier doesn't work in 3.3 when it used it work in 3.2

as shown in the screenshot below

  • with @3.3, in the repro, one line of text should be yellow but is pink instead

image

  • with @3.2 we observe the correct behavior

image


P.S: in App.vue

<template>
  [...]
  <span class="block classic-apply">this is the target of an @apply rule</span>
  [...]
</template>

<style scoped>
/* A */
.classic-apply {
  @apply text-xl text-orange-700 dark:text-white;
}
</style>

/* B */
<style>
.wrapper .child-text-global {
  @apply text-sky-700 dark:text-purple-300;
}
</style>

we show that the dark modifier do work with

  • (A.) apply + dark: does work for elements in the same SFC inside a scoped style block
  • (B.) apply + dark: does work inside a global style block

P.P.S: As stated in the vue doc here
https://vuejs.org/api/sfc-css-features.html#scoped-css

vue transforms this

<style scoped>
.a :deep(.b) {
  /* ... */
}
</style>

into this

.a[data-v-f3f3eg9] .b {
  /* ... */
}

so this issue might not be only related to an interaction vuejs

@RobinMalfait
Copy link
Member

@thecrypticace do you think this will already be solved by: #10943 & #10962?

@adamwathan
Copy link
Member

@RobinMalfait Nah this is a Vue issue, we can reproduce it without using Tailwind at all. We're in the middle of researching some workarounds to recommend in the mean time, should have something some time today 👍

@thecrypticace
Copy link
Contributor

thecrypticace commented Apr 18, 2023

Hey, this is happening because we now use the :is(…) selector in a few places to ensure more correct and composable behavior for dark, rtl/ltr variants, important selectors, etc…

We've done some poking around and it appears that Vue isn't handling :is properly.

Here's an example with Vue and raw CSS that doesn't work like I'd expect:

https://play.vuejs.org/#eNqtkM0OgyAQhF+FcLIH9W5pk76HFwubSEqFwKptjO9etBqxv2nS28Ay3yzT0YMxSVMDzShDOBtVIOzzihAmZDOKuyRcFc7tctrawhiwOZ2GD2NeSiVihAv6FwgOWRqAQh26RGFP74jPgb9ErkNfo+NWYqlrjKX7S8qiZ8XSoFt/dHhVQBzXBoS/SaZFSCYATJQsWRvSDRyulbYZsSC2edUPiEy6KBlqIx/Ma/dR1TDb19aggG8rLBCWjr/w69P+Bi9hv/A=

Here you can see the styles are:

.wrapper[data-v-472cff63] .child-text {
  color: red;
}
[data-v-472cff63]:is(.dark .wrapper :deep(.child-text)) {
  color: blue;
}
.dark .wrapper-without-is[data-v-472cff63] .child-text {
  color: blue;
}

Where you'd expect the 2nd selector to be this instead:

:is(.dark .wrapper[data-v-472cff63] .child-text) {
  color: blue;
}

So this isn't really an issue of @apply per se but of interactions about how the variants are now implemented using :is() and Vue's custom :deep() selector. I'm going to work on a write up and open an issue with Vue about this.

In the meantime, you can work around this by using @csstools/postcss-is-pseudo-class which is a PostCSS plugin that removes any wrapping :is() from selectors. While it does result in slightly different behavior it should be sufficient for most use cases — and will match how the selectors were written before v3.3.

You can install it using npm install @csstools/postcss-is-pseudo-class and then you'll need to update your postcss.config.js to look like this:

module.exports = {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
    "@csstools/postcss-is-pseudo-class": {},
  },
};

I've opened a PR against your reproduction repo to show you what this looks like in practice: remiconnesson/tailwind-vue-deep-apply-dark-bug#1

Let me know if you have any more questions! ✨

@doutatsu
Copy link

If this is a Vue issue, has anyone opened an issue in Vue.js on this? Been trying to find something, but can't - it would be good for Vue to fix this issue, rather than having to use a workaround. For now, it seems I am blocked form upgrading Tailwind

@doutatsu
Copy link

doutatsu commented Jun 5, 2023

@thecrypticace

I'm going to work on a write-up and open an issue with Vue about this.

You mentioned you were going to open an issue on this - if you haven't done it so far, should I go ahead and open it myself with a link to this issue?

@doutatsu
Copy link

doutatsu commented Aug 5, 2023

Issue opened on Vue ^. Appreciate additional contributions on there to get the ball rolling

@adamwathan
Copy link
Member

Here's a relevant PR someone has opened to fix this in Vue, just to connect the dots here:

vuejs/core#8929

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

No branches or pull requests

5 participants