Files
gh-ypares-agent-skills-ypar…/skills/textual-builder/references/styling.md
2025-11-30 09:08:16 +08:00

4.4 KiB

Styling with CSS

CSS Files

Link external CSS file:

class MyApp(App):
    CSS_PATH = "app.tcss"  # Textual CSS file

Or inline CSS:

class MyApp(App):
    CSS = """
    Screen {
        background: $background;
    }
    """

Selectors

Type Selectors

Target all widgets of a type:

Button {
    width: 100%;
}

Label {
    color: cyan;
}

ID Selectors

Target specific widget:

#my-button {
    background: red;
}

#header {
    dock: top;
}

Class Selectors

Target widgets with specific class:

.card {
    border: round white;
    padding: 1;
}

.selected {
    background: yellow;
}

Add classes in Python:

widget = Label("Text", classes="card selected")
# or
widget.add_class("highlighted")
widget.remove_class("selected")
widget.toggle_class("active")

Pseudo-classes

Style based on state:

Button:hover {
    background: $accent;
}

Button:focus {
    border: double green;
}

Input:disabled {
    opacity: 0.5;
}

Common pseudo-classes: :hover, :focus, :focus-within, :disabled, :enabled

Combinators

/* Direct children */
Container > Label {
    color: white;
}

/* Descendants */
Container Label {
    margin: 1;
}

/* Class and type */
Label.card {
    border: round;
}

Colors

Named Colors

Widget {
    color: red;
    background: blue;
    border: green;
}

Hex Colors

Widget {
    color: #ff0000;
    background: #00ff0088;  /* With alpha */
}

RGB/RGBA

Widget {
    color: rgb(255, 0, 0);
    background: rgba(0, 255, 0, 0.5);
}

Theme Variables

Use built-in theme colors:

Widget {
    background: $background;
    color: $text;
    border: $primary;
}

Common theme variables:

  • $background - Main background
  • $surface - Surface color
  • $panel - Panel background
  • $boost - Highlighted background
  • $primary - Primary accent
  • $secondary - Secondary accent
  • $accent - Accent color
  • $text - Main text color
  • $text-muted - Muted text
  • $foreground-muted - Dimmed foreground

Borders

Border Styles

Widget {
    border: solid red;      /* Style and color */
    border: round cyan;     /* Rounded border */
    border: double white;   /* Double line */
    border: dashed yellow;  /* Dashed */
    border: heavy green;    /* Heavy/thick */
    border: tall blue;      /* Tall characters */
}

Border Sides

Widget {
    border-top: solid red;
    border-bottom: round blue;
    border-left: double green;
    border-right: dashed yellow;
}

Border Title

Widget {
    border: round white;
    border-title-align: center;
}

Set title in Python:

widget.border_title = "My Widget"

Text Styling

Text Properties

Label {
    text-style: bold;
    text-style: italic;
    text-style: bold italic;
    text-style: underline;
    text-style: strike;
}

Text Alignment

Static {
    text-align: left;
    text-align: center;
    text-align: right;
}

Keylines

Add separators between grid cells or flex items:

Grid {
    keyline: thin green;
    keyline: thick $primary;
}

Note: Must be on a container with a layout.

Opacity

Widget {
    opacity: 0.5;    /* 50% transparent */
    opacity: 0;      /* Fully transparent */
    opacity: 1;      /* Fully opaque */
}

Tint

Apply color overlay:

Widget {
    tint: rgba(255, 0, 0, 0.3);  /* Red tint */
}

Rich Markup

Use Rich markup in text:

label = Label("[bold cyan]Hello[/bold cyan] [red]World[/red]")
label.update("[underline]Updated[/underline]")

Common markup:

  • [bold]...[/bold] - Bold
  • [italic]...[/italic] - Italic
  • [color]...[/color] - Colored (e.g., [red], [#ff0000])
  • [underline]...[/underline] - Underline
  • [strike]...[/strike] - Strikethrough
  • [link=...]...[/link] - Link

Example: Card Styling

.card {
    width: 12;
    height: 10;
    border: round $secondary;
    background: $panel;
    padding: 1;
    content-align: center middle;
}

.card:hover {
    background: $boost;
    border: heavy $primary;
}

.card.selected {
    background: $accent;
    border: double $primary;
}

.card.disabled {
    opacity: 0.5;
    tint: rgba(0, 0, 0, 0.5);
}

.card-title {
    text-style: bold;
    text-align: center;
    color: $text;
}

.card-value {
    text-align: center;
    color: $text-muted;
}