HTMLElment.style

I’d like to set styles on an element using this API: HTMLElement.style - Web APIs | MDN

This works in normal JavaScript:
element.style.background = "blue"

How can I use this in ReScript? I have a Webapi.Dom.Element.t.

(In case you’re wondering, yes there’s a good reason I can’t use React in this situation.)

YOLO

@set
external style: (Webapi.Dom.Element.t, {..}) => unit = "style"

@val
external someElement: Webapi.Dom.Element.t = "someGlobalElement"

someElement->style({"background-color": "blue"})

which compiles to

someGlobalElement.style = {
  "background-color": "blue"
};

Playground Link

You can also replace the open JS object type definition ({..}) with a more concrete definition as well to restrict to certain set of attributes…

Currently not aware of any copy-pastable module that covers the whole CSS spec, except the one implemented in rescript-react here… you might just copy paste that and adapt it to your needs and call it Style.res or something.

If you want to write single attributes, that’s going to be a little different. Something like this:

module Style = {
  type t
  
  @set external backgroundColor: (t, string) => unit = "backgroundColor"
}

@get
external style: Webapi.Dom.Element.t => Style.t = "style"

@val
external someElement: Webapi.Dom.Element.t = "someGlobalElement"

someElement->style->Style.backgroundColor("blue")

which compiles to something like:

var Style = {};

someGlobalElement.style.backgroundColor = "blue";

Playground Link

Can I set arbitrary individual properties? I was hoping to support this sort of api:
let setStyle = (element: Webapi.Dom.Element.t, property: string, value: string): unit => ...

Yeah you can do that too!

type element

@get external style: (element) => {..} = "style"

@val external someElement: element = "someElement"

(someElement->style)["background-color"] = "blue"

Unfortunately, our precedence for -> and [] is pretty messed up, that’s why you need to wrap the pipe call in parenthesis. You can actually also just put style in a binding and manipulate that separately… same results :joy:

I think @nickretallack is trying to set a style using a dynamic key, something like setStyle(element, "color", "red") right?

If yes, you can do this using Js.Dict.t (but I don’t recommend it):

module Dom = {
 type element
  
 @get external style: element => Js.Dict.t<string> = "style"
}

let setStyle = (element, key, value) => Js.Dict.set(Dom.style(element), key, value)
1 Like

I was going to post the same thing:

type element

@get external style: (element) => Js.Dict.t<string> = "style"

@val external someElement: element = "someElement"

let someAttr = "background-color"
someElement->style->Js.Dict.set(someAttr, "blue")

But why?

It’s totally my opinion :sweat_smile: , but I think in some cases it’s okay!

1 Like