Bubbling not working as expected
Windvis opened this issue · 12 comments
Hey there!
I'm experimenting with a new PostCSS setup based on postcss-nested and Tailwind.
Tailwind has a set of @rules which I want to let play nice with postcss-nested. More specifically the @screen and @variants rules.
I added both to the bubble
option of postcss-nested.
I'm trying to transform the following code:
.dummy-component {
@apply p-8 rounded shadow bg-white border;
&__content {
@apply font-thin font-sans text-5xl text-center;
}
@screen xl {
@apply w-1/3; /* This doesn't work */
width: calc(100% / 3); /* This does */
}
/* @media behaves exactly the same */
@media (min-width: 768px) {
@apply w-1/2; /* This doesn't work */
width: 50%; /* This does */
}
@variants hover {
@apply border-green;
border-color: lime;
}
}
And this is the result (before Tailwind does its thing):
.dummy-component {
@apply p-8 rounded shadow bg-white border;
}
.dummy-component__content {
@apply font-thin font-sans text-5xl text-center;
}
@screen xl {
.dummy-component {
/* This doesn't work */
width: calc(100% / 3); /* This does */
}
@apply w-1/3;
}
/* @media behaves exactly the same */
@media (min-width: 768px) {
.dummy-component {
/* This doesn't work */
width: 50%; /* This does */
}
@apply w-1/2;
}
@variants hover {
.dummy-component {
border-color: lime;
}
@apply border-green;
}
The @apply rules (which Tailwind uses to "mixin" styles) don't get nested in the bubbled selector as classic css rules do.
Any idea what could be causing this?
Maybe this option will help you
No, that's what I'm using at the moment. The problem seems to be that at-rules children won't we bubbled. It seems to be coded that way.
OK. Can you show the expected output?
Sorry, CSS example is too long, it is hard to me to understand it.
Yea sure, sorry!
Input:
.class {
@screen xl { /* 'screen' is added to the bubble option of postcss-nested */
@apply w-1/3; /* I want this to behave like a normal css rule */
width: calc(100% / 3); /* Like this */
}
}
expected output:
@screen xl {
.class {
@apply w-1/3;
width: calc(100% / 3);
}
}
actual output:
@screen xl {
.class {
width: calc(100% / 3);
}
@apply w-1/3; /* It doesn't get nested inside the selector */
}
And what are your postcss-nested
options?
{ bubble: ['screen'] }
Sorry. Still had no time to fix it. Will try to do it on this weekend.
No worries man! It's open source, I could do it myself if it was blocking :-D. Besides It looks like it works like this by design, so there must be use cases where this behaviour is desired :-)
@Windvis the solution is:
const cssNested = require('postcss-nested')
mix.postCss('resources/css/app.css', 'public/css', [
tailwindcss('tailwind.js'),
cssNested({ bubble: ['screen'] }),
])
call postcss-nested
plugin after tailwindcss
mentiond by adam wathan tailwindlabs/tailwindcss#94 (comment)
From @ai comments in the postcss-mixins
module: postcss/postcss-mixins#110 (comment)
I have tried the following patch:
diff --git a/index.js b/index.js
index d933ad1e91dd..05ea9d9b1206 100644
--- a/index.js
+++ b/index.js
@@ -190,7 +190,7 @@ module.exports = (opts = {}) => {
return {
postcssPlugin: 'postcss-nested',
- Once (root, { Rule }) {
+ AtRule (root, { Rule }) {
function process (node) {
node.each(child => {
if (child.type === 'rule') {
@@ -201,7 +201,10 @@ module.exports = (opts = {}) => {
})
}
process(root)
- }
+ },
+ Rule (root, { Rule }) {
+ processRule(root, bubble, unwrap, preserveEmpty, Rule)
+ },
}
}
module.exports.postcss = true
However I get the following error when I build:
ERROR in ./storybook/styles.css
Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js):
ModuleBuildError: Module build failed (from ./node_modules/postcss-loader/dist/cjs.js):
TypeError: Cannot set property 'parent' of undefined
at /Users/dan/coding/postcss-project/storybook/components/menu.css:366:3
at Root.removeChild (/Users/dan/coding/postcss-project/node_modules/postcss/lib/container.js:238:38)
at Root.removeChild (/Users/dan/coding/postcss-project/node_modules/postcss/lib/root.js:21:18)
at Proxy.remove (/Users/dan/coding/postcss-project/node_modules/postcss/lib/node.js:72:19)
at processRule (/Users/dan/coding/postcss-project/node_modules/postcss-nested/index.js:168:39)
at Rule (/Users/dan/coding/postcss-project/node_modules/postcss-nested/index.js:206:7)
If I comment out the following line in the postcss-nested
module:
if (rule.nodes.length === 0) rule.remove()
Then it builds but I have many nested @media
selectors at the top of the CSS file instead of where they would end up before (after the parent where they are nested from), as well as many empty selectors like .some-class {}
However I get the following error when I build
Yeap, that changes are not enough. We need to debug and change the origin functions.
Can you try 5.0.6 release. The bug may be fixed by @bsak-shell in #137