Skip to content

Instantly share code, notes, and snippets.

@jossmac
Created October 13, 2025 21:15
Show Gist options
  • Select an option

  • Save jossmac/83c97d4a64ba8c84b99d36f7dc8af2bc to your computer and use it in GitHub Desktop.

Select an option

Save jossmac/83c97d4a64ba8c84b99d36f7dc8af2bc to your computer and use it in GitHub Desktop.
CSS custom properties in TS/React `style` attribute. Alternative to module declarations, or comment directives.
import type { CSSProperties } from 'react';
type StyleVars = Record<
`--${string}`,
string | number | boolean | undefined | null
>;
/**
* Type casting identity function. Maintains the autocompletion and type safety
* of `CSSProperties`, while allowing the addition of CSS variables.
*
* @example
* <div
* className="flex items-[--align] transition-opacity"
* style={styleVars({
* opacity: props.visible ? 1 : 0,
* '--align': props.align,
* })}
* />
*/
export function styleVars(properties: CSSProperties & StyleVars) {
return properties as CSSProperties;
}
@jossmac
Copy link
Author

jossmac commented Oct 13, 2025

Module declarations can cause issues, especially when working in a large repo with lots of dependencies. A bit like modifying built-in prototypes, it'll eventually come back to bite you.

Naive type assertions undermine type safety.

<div
  style={{
    heihgt: 100, // Invalid property name ignored
    width: 200,
    '--some-variable': 'value',
  } as CSSProperties}
/>

Comment directives are probably the "safest" approach but they get tedious and can look messy.

<div
   className="flex items-[--align] transition-opacity"
-  style={{
+  style={styleVars({
     opacity: props.visible ? 1 : 0,
-    // @ts-expect-error — vars are valid CSS properties
     '--align': props.align,
-  }}
+  })}
 />

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment