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

CSS transformer does not visit nested rules #3573

Open
4 tasks done
jods4 opened this issue Feb 22, 2024 · 5 comments
Open
4 tasks done

CSS transformer does not visit nested rules #3573

jods4 opened this issue Feb 22, 2024 · 5 comments

Comments

@jods4
Copy link

jods4 commented Feb 22, 2024

UnoCSS version

0.58.5

Describe the bug

theme(..) is replaced by appropriate constant color in CSS rules that are included in my Vite project but it's left untouched when using CSS nesting.

You can checkout live playground link below but basically:

/* Input */
.top {
  color: theme('colors.red.400');
  
  .nested {
    color: theme('colors.red.400');
  }
}

/* Output */
.top {
  color: #f87171;
  
  .nested {
    color: theme('colors.red.400');
  }
}

Reproduction

https://unocss.dev/play/?html=Q&config=PTAEFMGcBsEsDsAuBaAJrSBDARtcz5wAPFOQ0eAe2QCcpEbYBjRcVZWAWwAdKbFIAKC69%2BoAN6DQoVOABmCcAGFK8BQHMANFNDc6kcIgCCiBrGwBXRLDkBPbdL1RDASSarID3fsMBVKtoAvqByNJScoADkFlRMkJCRwjx8iKAMmPCQcnyc4DQAIrB0LLAAblAhYRGRAAIxlHGQwOmZ2TS5NGhF4CXlCYKCxKKpsnKYFtAj8ooqarDqABSS0jQTUABcoADaOtJbkUwWkIjhtGuRmhKg7tB8m5F0qJGggQC6Xu86kAAWKYcCm2W0iih2Opx%2BfyskXurBIyGg6jSxBQfAy6nAoF%2B5Ro61hKFYmGgFx0gS8TgMAO2u28zkQ-koCwAlF5HD5jKZGJZrHYmSyaRS3B4ltTpJAmITwJsAIwAOgATHzpExUPB7t9TNxIOsQFBODKfsBicCXsydJ9pC0sjk8lqqcbLW0OoVitY%2BryzUFGYIgA&css=PQKgBA6gTglgLgUzAYwK4Gc4HsC2YDCAyoWABYJQIA0YAhgHYAmYcUD6AZllDhWOqgAOg7nAB0YAGLcwCAB60cggDYIAXGBDAAUGOyCwAb21gUWZdw1xyvABQByZOe7oxlRmIAsABm-2AlADcJmBi9AiYCMzGpqZOFlBWNggO8S5uUV6%2BAcGmAL7aBUA&options=N4IgLgTghgdgzgMwPYQLYGECucxIwZXxAC5JMBTAXyA

System Info

Reproduces in playground, see link above

Validations

@nevirum
Copy link

nevirum commented Feb 25, 2024

I recently decided to remove scss from the project and use lightningcss, I managed to adapt everything except the media query, I thought about replacing them with @screen, but the problem with nested rules does not allow me to completely remove scss

@zyyv
Copy link
Member

zyyv commented Apr 30, 2024

Hi @jods4 , unocss directives use css-tree parsing the css code generate a css ast, but upstream (css-tree) doesn't support parse nest class, so uno can't transform the nest class too.

Refer to csstree/csstree#210

@jods4
Copy link
Author

jods4 commented Apr 30, 2024

Hi @zyyv, I don't think that's exact.

css-tree does (to some extent) support nested rules, check this demo out:
https://stackblitz.com/edit/csstree-nested-attr-selector-repro-ytqcdm?file=index.js

The issue you refer is about maintaining a stack of selectors to know the complete selector you're working on (something I believe unocss doesn't need?). A css-tree member indicates that while this is not available out-of-the-box, it can be built on top of css-tree, indicating that parsing actually works.

That being said, it looks like the parsing has limitations with respect to the final CSS Nesting syntax. Selectors starting with & work, but relaxed selectors (without a leading &) do not seem to be supported yet. See: csstree/csstree#268

I observe that unocss seems to never transform nested rules, even if they start with &.

@zyyv
Copy link
Member

zyyv commented Apr 30, 2024

You can try this code, the css-tree skip the nest code parse, i think the problem from upstream.

import * as csstree from 'css-tree';

let ast = csstree.parse(`
  a {
    color: var(--foo);
    b {
      color: theme('bar');
    }
  }
`);

csstree.walk(ast, {
  visit: 'Function',
  enter(node) {
    console.log(node.type, node.name);
  },
});

Output only:

Function var

@jods4
Copy link
Author

jods4 commented Apr 30, 2024

@zyyv yes, that's the issue I've linked in my previous comment: it seems css-tree does not support the final "relaxed" CSS nesting syntax yet (when you don't use &).

On the other hand, if you try the stackblitz link above you'll see that nesting syntax already works when the nested selector starts with &.

Here's your example slightly modified:

import * as csstree from 'css-tree';

let ast = csstree.parse(`
  a {
    color: var(--foo);
    &:hover {
      color: theme('bar');
    }
  }
`);

csstree.walk(ast, {
  visit: 'Function',
  enter(node) {
    console.log(node.type, node.name);
  },
});

Output:

Function var
Function theme

(Stackblitz of this new example: https://stackblitz.com/edit/csstree-nested-attr-selector-repro-t2fhdl?file=index.js)

So it's not flawless yet but it already has support.

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

3 participants