'How to define css variables in style attribute in React and typescript

I want to define jsx like this:

<table style={{'--length': array.lenght}}>
   <tbody>
      <tr>{array}</tr>
   </tbody>
</table>

and I use --length in CSS, I also have cells that have --count that shows count using CSS pseudo selector (using the counter hack).

but typescript throws error:

TS2326: Types of property 'style' are incompatible.
  Type '{ '--length': number; }' is not assignable to type 'CSSProperties'.
    Object literal may only specify known properties, and ''--length'' does not exist in type 'CSSProperties'.

is it possible to change type of style attribute to accept CSS variable (custom properties) or is there a way to force any on style object?



Solution 1:[1]

Like this:

function Component() {
  const style = { "--my-css-var": 10 } as React.CSSProperties;
  return <div style={style}>...</div>
}

Or without the extra style variable:

function Component() {
  return <div style={{ "--my-css-var": 10 } as React.CSSProperties} />
}

Solution 2:[2]

You can add a type assertion to the variable. i.e. {['--css-variable' as any]: value }

<table style={{['--length' as any]: array.length}}>
   <tbody>
      <tr>{array}</tr>
   </tbody>
</table>

Solution 3:[3]

Casting the style to any defeats the whole purpose of using TypeScript, so I recommend extending React.CSSProperties with your custom set of properties:

import React, {CSSProperties} from 'react';

export interface MyCustomCSS extends CSSProperties {
  '--length': number;
}

By extending React.CSSProperties, you will keep TypeScript's property checking alive and you will be allowed to use your custom --length property.

Using MyCustomCSS would look like this:

const MyComponent: React.FC = (): JSX.Element => {
  return (
    <input
      style={
        {
          '--length': 300,
        } as MyCustomCSS
      }
    />
  );
};

Solution 4:[4]

you can simply put this module declaration merge using string templates at the top of the file or in any .d.ts file, then you will be able to use any CSS variable as long it starts '--' and that is string or number

import 'react';

declare module 'react' {
    interface CSSProperties {
        [key: `--${string}`]: string | number
    }
}

for example

<div style={{ "--value": percentage }} />

Solution 5:[5]

import "react";

type CustomProp = { [key in `--${string}`]: string };
declare module "react" {
  export interface CSSProperties extends CustomProp {}
}

put this in your global.d.ts file

Solution 6:[6]

I would like to add a different approach by using document.body.style.setProperty, and maybe if your css variable will be affected by certain props you can put it in a useEffect like this:

useEffect(() => {
    document.body.style.setProperty(
      "--image-width-portrait",
      `${windowSize.width - 20}px`
    );
}, [windowSize])

Later inside your css file you can call it like this:

width: var(--image-width-portrait);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Giorgio Polvara - Gpx
Solution 2 Aifos Si Prahs
Solution 3 Benny Neugebauer
Solution 4 Jayant Bhawal
Solution 5 BeanBro
Solution 6 Kira