or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

breakpoints.mdcolor.mdcomponent.mdcss-calc.mdcss-var.mdindex.md
tile.json

css-calc.mddocs/

CSS Calculations

Type-safe CSS calc() expression builder with chainable operations for dynamic styling and responsive calculations.

Capabilities

Calc Function

Create CSS calc() expressions with a fluent, chainable API.

/**
 * Create a chainable CSS calc() expression
 * @param x - Initial operand (number, string, or CSSVar)
 * @returns CalcChain for chaining operations
 */
function calc(x: Operand): CalcChain;

type Operand = string | number | CSSVar;

interface CalcChain {
  /** Add operands to the expression */
  add: (...operands: Operand[]) => CalcChain;
  /** Subtract operands from the expression */
  subtract: (...operands: Operand[]) => CalcChain;
  /** Multiply the expression by operands */
  multiply: (...operands: Operand[]) => CalcChain;
  /** Divide the expression by operands */
  divide: (...operands: Operand[]) => CalcChain;
  /** Negate the expression */
  negate: () => CalcChain;
  /** Convert to CSS calc() string */
  toString: () => string;
}

interface CSSVar {
  variable: string;
  reference: string;
}

Usage Examples:

import { calc } from "@chakra-ui/theme-tools/css-calc";
import { cssVar } from "@chakra-ui/theme-tools/css-var";

// Basic calculations
const simpleCalc = calc("100%").subtract("20px").toString();
// Returns: "calc(100% - 20px)"

const complexCalc = calc("50vw")
  .subtract("2rem")
  .multiply(2)
  .add("10px")
  .toString();
// Returns: "calc((50vw - 2rem) * 2 + 10px)"

// With CSS variables
const containerWidth = cssVar("container-width");
const spacing = cssVar("spacing");

const dynamicWidth = calc(containerWidth)
  .subtract(spacing)
  .multiply(0.5)
  .toString();
// Returns: "calc((var(--container-width) - var(--spacing)) * 0.5)"

// Negate values
const negativeMargin = calc("1rem").negate().toString();
// Returns: "calc(-1rem)"

Static Methods

Use static methods for direct calculations without chaining.

/**
 * Static methods available on calc function
 */
const calc: {
  /** Add multiple operands */
  add: (...operands: Operand[]) => string;
  /** Subtract operands (first - rest) */
  subtract: (...operands: Operand[]) => string;
  /** Multiply operands */
  multiply: (...operands: Operand[]) => string;
  /** Divide operands (first / rest) */
  divide: (...operands: Operand[]) => string;
  /** Negate an operand */
  negate: (operand: Operand) => string;
};

Usage Examples:

import { calc } from "@chakra-ui/theme-tools/css-calc";

// Static method usage
const addition = calc.add("50%", "20px", "1rem");
// Returns: "calc(50% + 20px + 1rem)"

const subtraction = calc.subtract("100vh", "60px", "2rem");
// Returns: "calc(100vh - 60px - 2rem)"

const multiplication = calc.multiply("100%", 0.8);
// Returns: "calc(100% * 0.8)"

const division = calc.divide("100vw", 3);
// Returns: "calc(100vw / 3)"

const negation = calc.negate("10px");
// Returns: "-10px" (or "calc(10px * -1)" for complex values)

Advanced Usage Patterns

Responsive Calculations

import { calc } from "@chakra-ui/theme-tools/css-calc";

// Container with responsive padding
const containerStyles = {
  width: calc("100vw").subtract("2rem").toString(), // Mobile padding
  maxWidth: "1200px",
  margin: "0 auto",
  
  // Responsive grid columns
  gridTemplateColumns: `repeat(auto-fit, minmax(${calc("300px").toString()}, 1fr))`,
  
  // Dynamic spacing based on viewport
  gap: calc("2vw").add("1rem").toString()
};

// Sidebar layout calculations
const sidebarWidth = "250px";
const headerHeight = "60px";

const layoutStyles = {
  sidebar: {
    width: sidebarWidth,
    height: calc("100vh").subtract(headerHeight).toString()
  },
  main: {
    width: calc("100%").subtract(sidebarWidth).toString(),
    height: calc("100vh").subtract(headerHeight).toString(),
    marginLeft: sidebarWidth
  }
};

Theme-based Calculations

import { calc } from "@chakra-ui/theme-tools/css-calc";
import { cssVar } from "@chakra-ui/theme-tools/css-var";

// Theme variables
const spacing = {
  xs: cssVar("spacing-xs", { fallback: "0.25rem" }),
  sm: cssVar("spacing-sm", { fallback: "0.5rem" }),
  md: cssVar("spacing-md", { fallback: "1rem" }),
  lg: cssVar("spacing-lg", { fallback: "2rem" })
};

// Card component with calculated dimensions
const cardStyles = {
  // Dynamic padding based on size variant
  small: {
    padding: calc(spacing.sm).multiply(2).toString(),
    margin: spacing.sm.reference
  },
  medium: {
    padding: calc(spacing.md).multiply(1.5).toString(),
    margin: spacing.md.reference
  },
  large: {
    padding: calc(spacing.lg).add(spacing.sm).toString(),
    margin: calc(spacing.lg).divide(2).toString()
  }
};

// Form layout calculations
const formSpacing = cssVar("form-spacing", { fallback: "1rem" });
const inputHeight = cssVar("input-height", { fallback: "2.5rem" });

const formStyles = {
  fieldGroup: {
    marginBottom: calc(formSpacing).multiply(1.5).toString()
  },
  label: {
    marginBottom: calc(formSpacing).divide(2).toString()
  },
  input: {
    height: inputHeight.reference,
    padding: calc(formSpacing).divide(2).toString()
  },
  textarea: {
    minHeight: calc(inputHeight).multiply(3).toString(),
    padding: calc(formSpacing).divide(2).toString()
  }
};

Animation and Transition Calculations

import { calc } from "@chakra-ui/theme-tools/css-calc";

// Staggered animation delays
const createStaggeredDelay = (index: number, baseDelay = 100) =>
  calc(baseDelay).multiply(index).add("ms").toString();

// Modal animations with calculated transforms
const modalAnimations = {
  enter: {
    transform: `translateY(${calc("-50px").toString()}) scale(0.9)`,
    opacity: 0
  },
  enterActive: {
    transform: "translateY(0) scale(1)",
    opacity: 1,
    transition: "all 300ms ease-out"
  },
  exit: {
    transform: `translateY(${calc("50px").toString()}) scale(0.9)`,
    opacity: 0,
    transition: "all 200ms ease-in"
  }
};

// Progress bar calculations
const progressBarStyles = (progress: number) => ({
  width: calc(progress).multiply("1%").toString(),
  transform: `translateX(${calc("-100%").add(calc(progress).multiply("1%")).toString()})`
});

Grid and Flexbox Calculations

import { calc } from "@chakra-ui/theme-tools/css-calc";

// CSS Grid with calculated gaps
const gridGap = "1rem";
const gridColumns = 3;

const gridStyles = {
  display: "grid",
  gridTemplateColumns: `repeat(${gridColumns}, ${calc("100%").divide(gridColumns).subtract(calc(gridGap).multiply(gridColumns - 1).divide(gridColumns)).toString()})`,
  gap: gridGap
};

// Flexbox with calculated flex-basis
const createFlexItem = (ratio: number, gap: string = "1rem") => ({
  flexBasis: calc(`${ratio * 100}%`).subtract(gap).toString(),
  marginRight: gap
});

const flexLayoutStyles = {
  container: {
    display: "flex",
    gap: "1rem"
  },
  sidebar: createFlexItem(0.25), // 25% width minus gap
  main: createFlexItem(0.75)     // 75% width minus gap
};