Tailwindcss: applyComplexClasses compiler stuck with @apply inside media queries or variants

Created on 19 Aug 2020  路  20Comments  路  Source: tailwindlabs/tailwindcss

Describe the problem:

With the new applyComplexClasses if you put @apply the old way: inside a @screen (media query) or a &:hover (variant), the complier gets stuck (using postcss loader in webpack).

Link to a minimal reproduction:

This css makes the compiler gets stuck (apply content can be anything):

.selector {
  @screen md {
    @apply w-2/6;
  }
}
.selector {
  &:hover {
    @apply text-white;
  }
}

I know the I should use the new way to @apply md:w-2/6 and @apply hover:text-white, but for backward compatibility could be good fixing this bug, or at least give an error in the compiler, right now it just gets stuck compiling.

Most helpful comment

It should probably just actually work so if we are going to make any changes to Tailwind making it work is the change I'd want to make. Just trying to offer some workaround in the mean time while I'm at some adventure farm with my 2 year old.

All 20 comments

This should be fixed mainly because it bugs also when you apply custom selectors where you don't have variants in the @apply:

.selector {
  @screen lg {
    @apply overflow-sub;
  }
}

Where @apply lg:overflow-sub is not possible when you don't want to set up apply variants for this selector.

This is a tough one to fix but I'm sure we can sort it out. In the mean time I would move your nesting plugin _before_ Tailwind so that there is no nested CSS left once the CSS is processed by Tailwind.

@adamwathan I moved postcss-nested _before_ Tailwind plugin, but still my build stuck

plugins: {
      'postcss-import': {},
      'postcss-nested': {},
      tailwindcss: {},
      'postcss-hexrgba': {},
      'postcss-custom-properties': {
        importFrom: [{customProperties}]
      },
      autoprefixer: {}
    }

@AndrewBogdanovTSS Can you share a repository that reproduces the issue? Way too hard to troubleshoot without unfortunately.

Edit: removed because not relevant to this issue

Please for the love of god someone just make a GitHub repository so I don't have to make one from scratch and I can probably fix it in 5 minutes between dad duty, but if I have to do it all myself it'll be days before I have a chance to play with it.

@adamwathan Created one for you: https://github.com/thecrypticace/at-apply-stuck

I'll note that it seems to get stuck with or without postcss-nested.

The bubble option in postcss-nested seems to just do nothing currently which is a problem. Need to configure it to bubble screen rules like this:

module.exports = {
  plugins: {
    'postcss-nested': {
      bubble: ['screen'],
    },
    tailwindcss: {},
  },
}

But it's not bubbling them :/

Actually nevermind the problem is the reproduction is setup incorrectly, it has a postcss.config.js file but it's using tailwind to build the CSS instead of PostCSS, so the config isn't being read.

I've set it up correctly and verified it's a bug in postcss-nested that prevents this from working currently unfortunately.

One fix I can think of is to write a separate PostCSS plugin that converts screen rules to media queries and switch to postcss-nesting, because nesting media queries with postcss-nested while using apply seems broken right now, even without Tailwind in the build process at all. It just doesn't produce the expected CSS to feed into Tailwind.

Here's my repo which shows the current bug:

https://github.com/adamwathan/at-apply-stuck

This is the bug we'd need to fix to have this working sensibly:

https://github.com/postcss/postcss-nested/issues/81

Best solution currently is just to not nest screen rules if you need to use apply, write them at the root level like regular CSS instead for now.

Ah whoops, sorry about that.

Since it still gets stuck w/o postcss-nested should tailwind still detect that and handle it gracefully (at least not seeming get stuck in a loop)?

It should probably just actually work so if we are going to make any changes to Tailwind making it work is the change I'd want to make. Just trying to offer some workaround in the mean time while I'm at some adventure farm with my 2 year old.

It should probably just actually work so if we are going to make any changes to Tailwind making it work is the change I'd want to make. Just trying to offer some workaround in the mean time while I'm at some adventure farm with my 2 year old.

You're awesome, next time I'll make a github with the problem sorry for my slack

Making this _work_ work is going to be a bit challenging but necessary anyways since there is a real CSS nesting spec and it's gonna probably exist for real one day.

Just a note for myself, I think the correct algorithm for applying styles in these situations is to generate the "applyable" selector (with the __TAILWIND-APPLY-PLACEHOLDER__ attribute selector), and split it on the placeholder, then stick the first half on the beginning of the _first_ selector in the tree, and the last half at the end of the _last_ selector in the tree.

Example:

.foo {
  .bar {
    .baz {
      @apply group-hover:opacity-50 hover:font-bold;
      // Applyable rules here are:
      //  .group\:hover [__TAILWIND-APPLY-PLACEHOLDER__]
      //  [__TAILWIND-APPLY-PLACEHOLDER__]:hover
    }
  }
}

Output should be:

.group\:hover .foo {
  .bar {
    .baz {
      opacity: .5;
    }
  }
}


.foo {
  .bar {
    .baz:hover {
      font-weight: 700;
    }
  }
}

Haven't thought through this bit in too much detail yet but another note for myself, think through what happens when people use & at the end of a nested selector because that could be dark.

This should be 95% fixed now (some really complex edge cases we don't handle yet but we will tackle soon). Going to close this but can capture the edge cases in a new issue.

Will tag new patch release in a couple min here.

@adamwathan one thing I just noticed when trying out applyComplexClasses in v.1.8.6 is that all of my !important statements are stripped out from the compiled code.
I use PostCSS with the next build config:

postcss: {
    // Allows the use of single line comments
    // in .pscss and .vue files
    parser: 'postcss-comment',
    plugins: {
      'postcss-import': {},
      tailwindcss: {},
      'postcss-nested': {},
      'postcss-hexrgba': {},
      'postcss-custom-properties': {
        importFrom: [{customProperties}]
      },
      autoprefixer: {}
    },
    preset: {
      // Change the postcss-preset-env settings
      autoprefixer: {
        grid: true
      }
    }
  },

than in my vue component I have

.swiper{
   &-pagination {
      bottom: -40px !important;
   }
}

resulting code just doesn't contain that !important:

.swiper-pagination {
    bottom: -40px;
}

without applyComplexClasses !important is there

I tried to use

'postcss-nested': { bubble: ['screen']},

above tailwindcss in the config but that that just makes build fail

also wanted to mention that it's not connected with purgeCSS since it was off

Do you mind opening a new issue for that? I鈥檓 going to forget about it if it鈥檚 just sitting here in this closed issue.

sure

Was this page helpful?
0 / 5 - 0 ratings

Related issues

paulhuisman picture paulhuisman  路  3Comments

lamberttraccard picture lamberttraccard  路  3Comments

chasegiunta picture chasegiunta  路  3Comments

jvanbaarsen picture jvanbaarsen  路  3Comments

nternetinspired picture nternetinspired  路  3Comments