Git Product home page Git Product logo

Comments (6)

tajo avatar tajo commented on June 2, 2024

I think the issue is with the SynchronizeHead component and the fact that it's overriding the insertRule method on the CSSStyleSheet prototype to create separate style tags in the head (styled-components only uses 1 style tag) and so the browser will treat the later style tags as more specific.

Having a single <style> tag vs multiple doesn't impact the specificity or priority, only the order of defined rules matter. That order is obviously reversed in your repro for some reason so the background is unchanged.

So something is wrong with the order of insertions coming form mui/styled-components or our implementation of addStyleElement / deleteStyleElement is wrong when it comes to positions.

Good step to verify if the issue is on our side would be to console.log arguments of those two functions and verify that rules are being added/deleted with correct indexes (in other words that the SC engine is executing insertRule / deleteRule as you would expect). You could also double-check that the SC engine doesn't use other window.CSSStyleSheet.prototype (deprecated) methods but afaik it shouldn't.

from ladle.

jkimbo avatar jkimbo commented on June 2, 2024

@tajo so I've patched the stackblitz to log out the rule and index and I get the following:

Screenshot 2024-01-18 at 16 37 41

They key part is that it looks like the .hjaLXG (which sets the background to red) is being inserted at index 0 and .UTfgf (the styles from mui) is also being inserted at index 0. It's possible that the native insertRule does something different with clashing indexes but I can't tell from the spec: https://drafts.csswg.org/cssom/#insert-a-css-rule

from ladle.

tajo avatar tajo commented on June 2, 2024

It's not in the spec but I guess it makes sense adding elements before existing index. https://github.com/tajo/ladle/blob/main/packages/ladle/lib/app/src/synchronize-head.tsx#L17 I think we just need to change after to before

from ladle.

jkimbo avatar jkimbo commented on June 2, 2024

I don't think changing after to before is sufficient. I just tried it in our internal Ladle instance and I still get the same issue. I think an additional problem is (since styled-components can insert rules out of order) if the index doesn't currently exist the rule just gets added to the head which means it's loses it's original index position: https://github.com/tajo/ladle/blob/main/packages/ladle/lib/app/src/synchronize-head.tsx#L19-L22

For example here are the rules on our Ladle instance:
Screenshot 2024-01-19 at 10 05 13

The key bit is that rule .cFjwwI is inserted at index 5 but because it's the first rule it effectively gets inserted at index 0. Other rules then get appended (which aren't important for this example) and then rule .driNVn gets inserted at index 1. This then overrides rule .cFjwwI which should be after .driNVn but stays at index 0.

I think to properly account for this we need to maintain a map of index to rule and regenerate all the stylesheets in the correct order after each insertion. What do you think?

from ladle.

tajo avatar tajo commented on June 2, 2024

Are we sure that there is just one instance of styled-components / CSS-in-JS library doing these insertions? It's really strange it attempts to insertRule at index 5 as its first operation. Not sure why would they do that. According to spec, that should just cause an error:

To insert a CSS rule rule in a CSS rule list list at index index, follow these steps:

  1. Set length to the number of items in list.
  2. If index is greater than length, then throw an IndexSizeError exception.

Anyway, if that's the case we could store the index value in the existing data-debug-css attribute and addStyleElement would prioritize that over the order of style tags. A bit mess. Something doesn't make sense right now.

from ladle.

jkimbo avatar jkimbo commented on June 2, 2024

@tajo there aren't multiple instances of styled-components on the page, it's because our .ladle/components.tsx file contains mui components and it seems they get rendered before the SynchronizeHead gets mounted. I've updated the demo to show that: https://stackblitz.com/edit/ladle-hzn2yy?file=.ladle%2Fcomponents.tsx

from ladle.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.