Skip to Content
ftui-styleOverview

Style Overview

ftui-style is the shared vocabulary for color and visual attributes across the entire FrankenTUI stack. Widgets compose styles with a CSS- like cascade; color profiles downgrade 24-bit RGB gracefully on older terminals; named styles live in a StyleSheet registry; Theme wires adaptive light/dark variants.

Nothing in this crate renders. It defines the types the render layer reads.

The four pieces

The cascade

Styles combine in CSS-like fashion: a child style inherits the parent’s values where the child hasn’t set its own. Attribute flags (bold, italic, etc.) OR together — both parent and child contribute. Colors are “most-specific wins”: a child’s fg overrides the parent’s.

parent: bold, fg: white child: fg: red combined: bold, fg: red

This is the Style::merge(parent) / Style::combine(other) contract. Details in the Style API page.

Color profiles

Terminals vary in color fidelity. ftui-style represents this explicitly and downgrades automatically:

TrueColor (24-bit) COLORTERM=truecolor ▼ if unavailable Ansi256 (8-bit) TERM contains "256" ▼ if unavailable Ansi16 (basic ANSI) default ▼ if NO_COLOR set Mono (black/white)

ColorProfile::detect() picks the right level from environment variables; Color::downgrade(profile) produces the best approximation via Euclidean distance in RGB space.

Named styles — the StyleSheet

Rather than hardcoding colors across widgets, register styles once and refer to them by name:

let sheet = StyleSheet::with_defaults(); let style = sheet.get("error").unwrap();

with_defaults populates the common semantic styles (error, warning, info, success, muted, highlight, link). See stylesheet.

Adaptive color and themes

pub enum AdaptiveColor { Fixed(Color), Adaptive { light: Color, dark: Color }, }

Theme composes a whole UI palette: primary, secondary, background, text, success, warning, error — with each color as an AdaptiveColor. The runtime decides light-vs-dark once (from terminal background or an explicit user choice) and resolves the theme for that choice.

Principles you can rely on

  • Cheap to copy. Style is Copy (28 bytes on x86_64). Passing it by value is idiomatic.
  • Hashable. Style derives Hash / Eq, so you can key a cache on styled content.
  • No hidden I/O. No println!, no file reads. Purely functional.
  • Forward-compatible. Extension fields live in the StyleSheet map and TableTheme’s spec layer, not in flags-by-bit.

Where to go next