stitchesjs / stitches

[Not Actively Maintained] CSS-in-JS with near-zero runtime, SSR, multi-variant support, and a best-in-class developer experience.
https://stitches.dev
MIT License
7.76k stars 254 forks source link

stitches' css is overriding classnames coming from third party lib #1111

Open triptu opened 2 years ago

triptu commented 2 years ago

Bug report

I was trying to figure out a way to implement the suggestion here but can't find a way to do it. It seems that stitches always creates a style tag and appends to the document head. If there is a style tag in the head already referencing a 3rd party lib(which gives some classnames), I'm not sure what would be the best way to go forward.

To Reproduce

const Text = styled("p", {
  color: blue
});

<Text className="color-yellow"/>

// the final output is of blue color than yellow

Also, check the discussion at - https://github.com/stitchesjs/stitches/issues/642

Expected behavior

The final output should be yellow

Additional Context

Another important point here is that the stitches part is also coming from a library(but this library is in our control). So the app is using a UI library based on stitches and tailwind for styling, or to override styles in the components coming from the UI library.

Suggestion for Solution

Taking the style tag in createStitches config instead of creating a style tag. This would allow the app to have control of the precedence order.

I'm open to submitting a PR for this if it makes sense.

Pranav2612000 commented 2 years ago

@triptu Facing the same issue. Were you able to come up with a solution?

Pranav2612000 commented 2 years ago

For anyone who stumbles here, I was able to find a temporary workaround by ensuring that stitches styles are injected as the first element in head, instead of the last element ( the default behaviour ).

This was done by modifying the dist/index.mjs file in the node_module package to change

(e.head||e).appendChild(document.createElement("style")) ...

to

(e.head||e).insertBefore(document.createElement("style"),(e.head||e).firstChild) ...

Note: This is just a quick temporary solution. Like @triptu I'm also open to polishing this approach and submitting a PR if the maintainers want something like this. Otherwise, and if there's enough interest, I can also create a fork ( if the maintainers approve )

utkarshk384 commented 1 year ago

@Pranav2612000 Thank you for the solution. I used your solution to create a naive fix if anyone needs it running in production.

  1. Create a folder in the root of your project and call it scripts. Then create a file called fixCssPrecedence.js inside that folder.
  2. Next add the following code to that file

    
    const fs = require("fs");

const PATH = "./node_modules/@stitches/react/dist/index.mjs";

try { let content = fs.readFileSync(PATH); content = String(content); content = content.replace( '(e.head||e).appendChild(document.createElement("style"))', '(e.head||e).insertBefore(document.createElement("style"),(e.head||e).firstChild)' );

fs.writeFileSync(PATH, content); } catch (e) { if (e.code == "ENOENT") console.log("Couldn't find file"); }

 3. Inside your `package.json` add the following scripts

scripts: { ...your other scripts "predev": "yarn fix-css", "prebuild": "yarn fix-css", "fix-css": "node ./scripts/fixCssPrecedence.js" }



 Now when your run your `dev` or `build` scripts it'll first replace the file content under `node_modules` and then run the main script.

Edit: This is working for `"@stitches/react": "^1.2.8"`