CSX CSS Utilities for TypeStyle
CSX (CSS eXpressions) is a utility library designed to simplify the creation of strongly typed CSS values and functions within TypeScript environments, primarily serving as a companion to the TypeStyle library. It offers a comprehensive set of helpers for common CSS properties and units, such as `color`, `rgb`, `hsl`, `px`, `em`, `percent`, as well as shorthand properties like `margin` and `padding`. The current stable version, 10.0.2, reflects ongoing development with a recent focus on aligning its output more closely with the CSS Object Model (CSSOM) for improved consistency and testability across different browsers and testing setups. This includes changes to color function spacing and the addition of optional alpha parameters for `rgb()` and `hsl()`. CSX maintains an active release cadence, delivering continuous enhancements and bug fixes. Its core differentiator lies in providing a robust, type-safe API for dynamic CSS value generation, significantly reducing runtime errors and improving code maintainability compared to raw string concatenation or less-typed approaches.
Common errors
-
Expected `rgb(0, 0, 0)` but got `rgb(0,0,0)` in CSS output.
cause Difference in color function string output due to new spacing introduced in v10.0.0 to align with CSSOM.fixThis is an intended breaking change in output formatting. Adjust any tests or code that performs exact string comparisons on color function outputs to reflect the new spaced format. No functional code change is needed. -
Type error: Argument of type 'string' is not assignable to parameter of type 'CssLength'.
cause Attempting to pass a raw string where a `csx` unit helper (like `px()`, `em()`) is expected, or providing an invalid value type to a CSX function.fixAlways use the appropriate CSX helper functions for units and values, e.g., `px(10)` instead of `'10px'`, or `percent(50)` instead of `'50%'`. Ensure types match the function signatures. -
ReferenceError: require is not defined
cause Attempting to import `csx` using CommonJS `require()` syntax in an environment (e.g., a modern TypeScript project, browser ES module context, or Node.js with type:"module") that expects ES module syntax.fixUpdate your import statements to use ES module syntax: `import { color } from 'csx';`. Ensure your project's `tsconfig.json` (if applicable) and build setup are configured for ES modules (e.g., `"module": "esnext"` or `"nodenext"`).
Warnings
- breaking CSS color functions (e.g., `rgb()`, `hsl()`) now include spaces after commas in their output to match the CSS Object Model (CSSOM). This changes the exact string output of color functions.
- breaking The behavior of `background-size` helper was fixed in `v9.0.2` to correctly use `/` between position and size. Code relying on the incorrect pre-`v9.0.2` output will produce different CSS.
- gotcha In `v9.0.2`, a more specific type definition was added for `background-size` that throws a type error if `size` is provided but `position` is undefined. This improves type safety but can break existing code that was implicitly passing `undefined` for position.
- breaking Starting with `v5.0.0`, all styles generated by CSX are vendor prefixed by default and are explicitly meant to be used in conjunction with TypeStyle. Using CSX independently of TypeStyle or in other styling solutions may lead to unexpected behavior or incomplete CSS output.
Install
-
npm install csx -
yarn add csx -
pnpm add csx
Imports
- color
const color = require('csx').color;import { color } from 'csx' - rgb
import rgb from 'csx/lib/rgb'
import { rgb } from 'csx' - px
import { px } from 'csx/dist/units'import { px } from 'csx' - margin
import * as csx from 'csx'; const m = csx.margin;
import { margin } from 'csx'
Quickstart
import { color, rgb, hsl, px, em, rem, percent, viewHeight, viewWidth, margin, padding, url, quote } from 'csx';
import { style } from 'typestyle'; // Assuming TypeStyle is used as recommended
// Define some CSS values using CSX helpers
const brandColor = color('#1E90FF'); // Dodger Blue
const semiTransparent = rgb(30, 144, 255, 0.7); // RGB with alpha
const lightAccent = hsl(200, 80, 95); // HSL color
// Unit helpers
const defaultPadding = px(16);
const headingFontSize = em(2.5);
const bodyFontSize = rem(1.1);
const viewportWidth = viewWidth(100);
const elementHeight = viewHeight(50);
const responsiveWidth = percent(75);
// Shorthand properties
const cardMargin = margin(px(20), 'auto'); // Top/Bottom 20px, Left/Right auto
const elementPadding = padding(defaultPadding, px(10)); // Top/Bottom 16px, Left/Right 10px
// URL and quoting helpers
const backgroundImage = url('/assets/background.jpg');
const fontFaceName = quote('My Custom Font');
// Example of integrating with TypeStyle
const myStyledElement = style({
color: brandColor.toString(),
backgroundColor: semiTransparent.toString(),
border: `${px(1)} solid ${lightAccent.toString()}`,
padding: elementPadding.toString(),
margin: cardMargin.toString(),
width: responsiveWidth.toString(),
height: elementHeight.toString(),
fontSize: bodyFontSize.toString(),
fontFamily: fontFaceName.toString(),
backgroundImage: backgroundImage.toString(),
$nest: {
'& > h1': {
fontSize: headingFontSize.toString(),
textAlign: 'center',
},
'@media (max-width: 768px)': {
width: viewportWidth.toString(),
margin: margin(px(10)),
},
},
});
console.log('CSX Brand Color:', brandColor.toString());
console.log('CSX Element Padding:', elementPadding.toString());
console.log('CSX Card Margin:', cardMargin.toString());
console.log('CSX Background Image:', backgroundImage.toString());
console.log('CSX Font Face Name:', fontFaceName.toString());
console.log('Generated TypeStyle class name:', myStyledElement);