hyperfiddle / electric

a reactive Clojure dialect for web development that uses a compiler to manage the frontend/backend boundary
Eclipse Public License 2.0
1.68k stars 42 forks source link

[dom2] Can't set CSS custom properties #39

Open ComedyTomedy opened 1 year ago

ComedyTomedy commented 1 year ago

dom2/style will only set properties that goog.style/setStyle recognises - anything else silently vanishes. This makes it impossible to use custom properties ("CSS variables"), and seems to affect browser-prefixed props too (I quickly tested -moz-transition, might be wrong about this).

Here are 2 attempts that don't work:

(dom/style {:--size (str x)})

(dom/props {:style (str "--size: " x)})

And one attempt that did:

(dom/set-attribute-ns dom/node
   nil "style" (str "--size: " x))

One possible fix might be for dom/set-property! to join style rules into a k: v; k2: v2 form and use set-attribute-ns to inject them as a string. It feels slightly hacky, and perhaps bypasses some clever internals of Google Closure (?), but it would solve the problem without styles overwriting oneanother.

(PS: I'm enjoying Electric v much, I'm not a dev, don't work in tech, and never used Clojure beyond toy examples, but Electric has revived my enthusiasm for a personal project that I abandoned last year. Thank you for everything!)

s-ol commented 1 year ago

the js API generally used to set CSS vars is element.style.setProperty(prop, val). This works for custom properties and browser properties equally, but I'm not sure what benefits goog.style has over using this browser API.

EDIT: having looked at the closure library, it doesn't seem to do anything useful and was probably added before setProperty was standardized (ca 2012).

dustingetz commented 8 months ago

Implemented for CSS vars. But not for all properties, e.g. -moz-transition. Need to confirm this:

Having looked at the closure library, it doesn’t seem to do anything useful and was probably added before setProperty was standardized (ca 2012).

ggeoffrey commented 8 months ago

goog.style.setStyle does two things that element.style.setProperty doesn’t:

  1. vendor autoprefixing: setStyle(element, {"orient": "vertical"}) will set -moz-orient to "vertical"
  2. direct access writes: setStyle will perform element.style.MozOrient = "vertical" instead of calling setProperty

I don’t know if 1. is useful. I don’t know if 2. has any benefit over setProperty

If 1. is not useful, then I agree with @s-ol and I think we should call setProperty directly.

ComedyTomedy commented 8 months ago

2. is referred to simply as alternative syntax in dev moz org

Personally I'd see 1. as undocumented magic -- the "rule of least surprise" would be that whatever property I enter gets added to the DOM and if it "doesn't work", that's my problem.