CELLIUM 006 - CSS Support
Summary:
Cellium has introduced basic CSS support, allowing developers to separate the visual styling of widgets from their structural definition. This currently includes ID and class selectors, as well as state-based styling for focused elements.
Introduction
One of the challenges in building Terminal User Interfaces (TUIs) is managing the visual properties of widgets without cluttering the layout logic. By adopting a subset of CSS, Cellium allows for a more declarative approach to styling.
While not 'perfect', the concepts of CSS styling widgets should allow for developers to be able to theme their work with familiar concepts.
Current State of CSS Support
The current implementation in css.erl provides several key features:
Selectors
Cellium supports two primary selectors:
- ID Selectors: Target specific widgets using
#widget_id. - Class Selectors: Target groups of widgets using
.class_name.
State-based Styling
The :focused pseudo-class is supported, enabling different styles when a widget has input focus. For example:
.button:focused {
color: black;
background-color: cyan;
}
Stylesheet Loading
Stylesheets can be loaded from external files using css:load_stylesheet/1, or the default styles can be applied via css:style/1.
Property Parsing
The parser currently handles:
- Integers (for colors and sizes)
- Booleans (
true,false) - Atoms (for general property values like colors or alignment)
- Note: at the moment it only allows for a single stylesheet, but I feel like it should allow for multiple style sheets.
Examples of Working CSS
Here are some examples of CSS rules that currently work in Cellium:
Basic Widget Styling
You can set colors and background colors using either standard color names (as atoms) or integer values if your terminal supports them.
.box {
color: white;
background-color: blue;
}
#sidebar {
background-color: black;
color: 7;
}
Layout Control
The expand property is used by containers to determine if a widget should take up all available space.
.main-content {
expand: true;
}
.fixed-sidebar {
expand: false;
width: 20;
}
Focus and Interactivity
You can define which widgets are focusable and how they look when they gain focus.
.input-field {
focusable: true;
background-color: black;
color: white;
}
.input-field:focused {
background-color: white;
color: black;
}
.button {
focusable: true;
color: cyan;
}
.button:focused {
color: black;
background-color: cyan;
}
Specialized Widget Properties
Some properties are specific to certain widget types, like title alignment for frames or debug borders for containers.
.bordered-frame {
title_align: center;
}
.debug-container {
debug: true;
}
Technical Implementation
When styling is applied, Cellium walks the layout tree and merges properties from the stylesheet into the widget maps. It prioritizes ID styles over class styles and focused styles over normal styles.
Crucially, the styling engine respects calculated layout properties like x, y, width, and height, ensuring that visual updates don't
accidentally break the layout positioning. As a developer you probably dont want to be messing with that in the css anyway.
Conclusion
While the current CSS support is a subset of the full specification, it provides a solid foundation for building themed and interactive terminal applications in Erlang.