stitchesjs / stitches

[Not Actively Maintained] CSS-in-JS with near-zero runtime, SSR, multi-variant support, and a best-in-class developer experience.

Home Page:https://stitches.dev

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

stitches' css is overriding classnames coming from third party lib

triptu opened this issue · comments

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 - #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.

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

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 )

@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");
}
  1. 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"