Skip to content

Utilities

To avoid the tedium of writing out styles explicitly over and over, Counterweight provides a variety of Tailwind-inspired "utility styles". These utilities are pre-defined styles that can be combined to form more complex styles.

The utilities can be imported from the counterweight.styles.utilities module. We recommend a * import for ease of use:

from counterweight.styles.utilities import *

That brings in the utilities, the palette's colors, and the ColorName, Shade and Side types the utility functions take, but not Style, Color or anything else the module itself imports, which come from counterweight.styles.

Each utility is a Style that sets just a small set of properties. Some are constants (e.g., border_heavy, justify_children_center), and the rest are functions that return one (e.g., gap(n), margin_x(n), pad(n)). Color utilities take a color name and shade, or any color. For example, border_color("rose", 200) returns a Style that sets the border color to rose-200, as does border_color(rose_200), with the palette's constant for that color:

from counterweight.styles import Style, CellStyle, Color

border_color("rose", 200) == Style(border_style=CellStyle(foreground=Color.from_hex("#fecdd3")))
border_color(rose_200) == border_color("rose", 200)

Since they are normal Styles, they can be combined to form more complex styles using the | operator. Here we make a new Style for a rose_200-colored heavy border on the top and bottom sides:

from counterweight.styles.utilities import *

border_heavy_top_bottom_rose_200 = border_y | border_heavy | border_color("rose", 200)

Actually giving a name to the new style is optional. We can also use the expression directly in our component:

from counterweight.styles.utilities import *
from counterweight.components import component
from counterweight.elements import Text


@component
def my_component() -> Text:
    return Text(
        content="Hello, world!",
        style=border_y | border_heavy | border_color("rose", 200),
    )

Performance Considerations

If you have an expression like border_y | border_heavy | border_color("rose", 200) in your component, it will be evaluated every time the component is rendered. Merging styles with | does take some time, though it is aggressively cached inside the framework. If you find that this is causing performance issues, you should create the style just once, ideally outside your component (i.e., at module scope), so that it runs only once.

Reference

Each table below is built from the utilities module when the docs are built. The constants' tables list every field each one sets. Fields not listed are left unset, so merging the utility into another style leaves them alone (see Merging). The functions' tables give their signatures, since what they set depends on their arguments.

default is the empty style, a starting point that sets nothing.

Utility Sets
default Nothing

Colors

The color utilities draw from Tailwind's color palette when given a ColorName such as "rose" and a Shade from 50 (lightest) to 950 (darkest). Given one color instead, they use it, as Tailwind's arbitrary values such as text-[#fbbf24] do: a Color, such as a palette constant or Color.from_hex("#fbbf24"), one of the terminal colors, or a gradient. text_white and text_black are outside the palette.

Each utility colors one part of a box. In the box below, every part has its own color, matched by the swatch beside the utility that paints it:

PLACES: tuple[tuple[str, ColorName, Shade], ...] = (
    ("margin_color", "indigo", 900),
    ("border_color", "amber", 400),
    ("border_bg", "slate", 600),
    ("padding_color", "teal", 700),
    ("content_color", "rose", 900),
    ("text_color", "lime", 300),
    ("text_bg", "sky", 800),
)


def legend_line(utility: str, color: ColorName, shade: Shade) -> Text:
    return Text(
        content=(
            Chunk(content="██ ", style=text_color(color, shade).text_style),
            Chunk(content=f'{utility}("{color}", {shade})'),
        )
    )


@component
def places() -> Div:
    return Div(
        style=row | gap(2) | align_children_center,
        children=(
            Div(
                style=width(26)
                | height(7)
                | center_children
                | margin(1)
                | margin_color("indigo", 900)
                | border
                | border_heavy
                | border_color("amber", 400)
                | border_bg("slate", 600)
                | pad_x(2)
                | pad_y(1)
                | padding_color("teal", 700)
                | content_color("rose", 900),
                children=(Text(style=text_color("lime", 300) | text_bg("sky", 800), content="Some text"),),
            ),
            Div(style=col, children=tuple(legend_line(*place) for place in PLACES)),
        ),
    )

Each color utility painting its part of a box

 ┏━━━━━━━━━━━━━━━━━━━━━━━━┓   ██ margin_color("indigo", 900)
 ┃                        ┃   ██ border_color("amber", 400) 
 ┃                        ┃   ██ border_bg("slate", 600)    
 ┃        Some text       ┃   ██ padding_color("teal", 700) 
 ┃                        ┃   ██ content_color("rose", 900) 
 ┃                        ┃   ██ text_color("lime", 300)    
 ┗━━━━━━━━━━━━━━━━━━━━━━━━┛   ██ text_bg("sky", 800)        
Utility Sets
text_white text_style.foreground = #ffffff
text_black text_style.foreground = #000000
Function Description
text_color(color: ColorName, shade: Shade) -> Style
text_color(color: AnyColor | Gradient) -> Style
Color the text with a palette color, by name and shade, or with any color or gradient.
text_bg(color: ColorName, shade: Shade) -> Style
text_bg(color: AnyColor | Gradient) -> Style
Color the background behind the text with a palette color, by name and shade, or with any color or gradient.
border_color(color: ColorName, shade: Shade) -> Style
border_color(color: AnyColor | Gradient) -> Style
Color the border characters with a palette color, by name and shade, or with any color or gradient.
border_bg(color: ColorName, shade: Shade) -> Style
border_bg(color: AnyColor | Gradient) -> Style
Color the background behind the border characters with a palette color, by name and shade, or with any color or gradient.
margin_color(color: ColorName, shade: Shade) -> Style
margin_color(color: AnyColor | Gradient) -> Style
Fill the margin with a palette color, by name and shade, or with any color or gradient.
padding_color(color: ColorName, shade: Shade) -> Style
padding_color(color: AnyColor | Gradient) -> Style
Fill the padding with a palette color, by name and shade, or with any color or gradient.
content_color(color: ColorName, shade: Shade) -> Style
content_color(color: AnyColor | Gradient) -> Style
Fill the whole box with a palette color, by name and shade, or with any color or gradient, under any margin, padding and border colors.

Palette

Every palette color is also a Color constant named <color>_<shade>, such as rose_200, for style fields that take a Color directly. Hover over a swatch to see its name and hex code.

50100200300400500600700800900950
slate
gray
zinc
neutral
stone
red
orange
amber
yellow
lime
green
emerald
teal
cyan
sky
blue
indigo
violet
purple
fuchsia
pink
rose

counterweight.styles.utilities.ColorName module-attribute

ColorName = Literal[
    "slate",
    "gray",
    "zinc",
    "neutral",
    "stone",
    "red",
    "orange",
    "amber",
    "yellow",
    "lime",
    "green",
    "emerald",
    "teal",
    "cyan",
    "sky",
    "blue",
    "indigo",
    "violet",
    "purple",
    "fuchsia",
    "pink",
    "rose",
]

The name of one of the palette's colors, as the color utilities take it, such as "sky".

counterweight.styles.utilities.Shade module-attribute

Shade = Literal[
    50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950
]

One of the palette's shades, from lightest (50) to darkest (950), as in Tailwind's palette.

Terminal colors

A Color looks the same in every terminal. The terminal's own colors follow the user's theme instead, as the colors of a program run in it do: an IndexedColor is an entry of the terminal's 256-color palette, whose first 16 are the black, red, green, yellow, blue, magenta, cyan and white that themes set, then their bright forms, and TERMINAL_DEFAULT is the terminal's default foreground where it colors text, and its default background where it fills one. These utilities set them in each place the color utilities above do, the *_indexed ones taking a palette index from 0 to 255. Screenshots draw them in DEFAULT_PALETTE, and the defaults as white on black, as the first 16 indexed colors and the defaults are drawn below. In a terminal, they take whatever colors its theme gives them.

def swatch(index: int) -> Text:
    return Text(style=text_bg_indexed(index) | width(6) | text_justify_center, content=str(index))


@component
def terminal_colors() -> Div:
    return Div(
        style=col,
        children=(
            Div(style=row, children=tuple(swatch(index) for index in range(8))),
            Div(style=row, children=tuple(swatch(index) for index in range(8, 16))),
            Text(
                style=text_terminal_default | text_bg_terminal_default | margin_top(1) | pad_x(1),
                content="text_terminal_default | text_bg_terminal_default",
            ),
        ),
    )

The first 16 indexed colors and the terminal defaults, as screenshots draw them

   0     1     2     3     4     5     6     7    
   8     9    10    11    12    13    14    15    

 text_terminal_default | text_bg_terminal_default 
Utility Sets
text_terminal_default text_style.foreground = TerminalDefault()
text_bg_terminal_default text_style.background = TerminalDefault()
border_terminal_default border_style.foreground = TerminalDefault()
border_bg_terminal_default border_style.background = TerminalDefault()
margin_terminal_default margin_color = TerminalDefault()
padding_terminal_default padding_color = TerminalDefault()
content_terminal_default content_color = TerminalDefault()
Function Description
text_indexed(index: int) -> Style Color the text with entry index of the terminal's palette, which follows the user's theme.
text_bg_indexed(index: int) -> Style Color the background behind the text with entry index of the terminal's palette.
border_indexed(index: int) -> Style Color the border characters with entry index of the terminal's palette.
border_bg_indexed(index: int) -> Style Color the background behind the border characters with entry index of the terminal's palette.
margin_indexed(index: int) -> Style Fill the margin with entry index of the terminal's palette.
padding_indexed(index: int) -> Style Fill the padding with entry index of the terminal's palette.
content_indexed(index: int) -> Style Fill the whole box with entry index of the terminal's palette, under any margin, padding and border colors.

Gradients

A gradient in a color place maps over the box that place paints unless the gradient names its own box. The color utilities above take one, and these put one in each place too.

Function Description
text_gradient(gradient: Gradient) -> Style Color the text with a gradient, which maps over the content box unless it names another box.
text_bg_gradient(gradient: Gradient) -> Style Color the background behind the text with a gradient, which maps over the content box unless it names another.
border_gradient(gradient: Gradient) -> Style Color the border characters with a gradient, which maps over the border box unless it names another.
border_bg_gradient(gradient: Gradient) -> Style Color the background behind the border characters with a gradient, over the border box unless it names another.
margin_gradient(gradient: Gradient) -> Style Fill the margin with a gradient, which maps over the margin box unless it names another.
padding_gradient(gradient: Gradient) -> Style Fill the padding with a gradient, which maps over the padding box unless it names another.
content_gradient(gradient: Gradient) -> Style Fill the whole box with a gradient, under any margin, padding and border colors, which maps over the border box unless it names another.

Attributes

The text_* attributes draw the text bold, dim, italic, underlined or struck through, and the border_* ones draw the border characters that way. Each has a not_ form that turns it off when merged over a style that turns it on, such as a style for a selected row that isn't bold, merged over a table's bold one. text_link(uri) makes the text a hyperlink that the terminal opens when it's clicked, and text_link(None) makes it not a link, inside text that is one. They're CSS's font-weight: bold, font-style: italic and text-decoration, with dim, which a terminal draws faint, in place of CSS's lighter weights.

TEXT_ATTRIBUTES: tuple[tuple[str, Style], ...] = (
    ("text_bold", text_bold),
    ("text_dim", text_dim),
    ("text_italic", text_italic),
    ("text_underline", text_underline),
    ("text_strikethrough", text_strikethrough),
)

EMPHASIS = text_bold | text_italic | text_underline | text_color("amber", 300)


def bordered(utility: str, style: Style) -> Text:
    return Text(content=utility, style=border | border_heavy | border_color("sky", 400) | pad_x(1) | style)


@component
def attributes() -> Div:
    return Div(
        style=col | gap(1),
        children=(
            Div(
                style=col,
                children=tuple(Text(content=utility, style=style) for utility, style in TEXT_ATTRIBUTES),
            ),
            Div(
                style=col,
                children=(
                    Text(content="EMPHASIS", style=EMPHASIS),
                    Text(content="EMPHASIS | text_not_italic", style=EMPHASIS | text_not_italic),
                    Text(content="EMPHASIS | text_not_underline", style=EMPHASIS | text_not_underline),
                ),
            ),
            Div(
                style=row | gap(1),
                children=(
                    bordered("border_bold", border_bold),
                    bordered("border_dim", border_dim),
                    bordered("border_dim | border_not_dim", border_dim | border_not_dim),
                ),
            ),
        ),
    )

Each text attribute, a style turning two of its attributes off, and borders drawn bold and dim

text_bold                                                     
text_dim                                                      
text_italic                                                   
text_underline                                                
text_strikethrough                                            

EMPHASIS                                                      
EMPHASIS | text_not_italic                                    
EMPHASIS | text_not_underline                                 

┏━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ border_bold ┃ ┃ border_dim ┃ ┃ border_dim | border_not_dim ┃
┗━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

How each looks is up to the terminal and its font: some can draw bold text in a brighter color as well as, or instead of, a heavier weight, and a terminal whose font has no italic face can draw italic text upright.

Utility Sets
text_bold text_style.bold = True
text_not_bold text_style.bold = False
text_dim text_style.dim = True
text_not_dim text_style.dim = False
text_italic text_style.italic = True
text_not_italic text_style.italic = False
text_underline text_style.underline = True
text_not_underline text_style.underline = False
text_strikethrough text_style.strikethrough = True
text_not_strikethrough text_style.strikethrough = False
border_bold border_style.bold = True
border_not_bold border_style.bold = False
border_dim border_style.dim = True
border_not_dim border_style.dim = False
border_italic border_style.italic = True
border_not_italic border_style.italic = False
border_underline border_style.underline = True
border_not_underline border_style.underline = False
border_strikethrough border_style.strikethrough = True
border_not_strikethrough border_style.strikethrough = False
Function Description
text_link(uri: str | None) -> Style Make the text a hyperlink to uri, which the terminal opens when it's clicked, or with None, not a link.

Direction and wrapping

These set the flexbox main axis, and whether children wrap onto more lines when they don't fit. See Choosing a layout model and Wrapping without a grid.

Utility Sets
row layout.flex_direction = FlexDirection.Row
col layout.flex_direction = FlexDirection.Column
row_reverse layout.flex_direction = FlexDirection.RowReverse
col_reverse layout.flex_direction = FlexDirection.ColumnReverse
flex_no_wrap layout.flex_wrap = FlexWrap.NoWrap
flex_wrap layout.flex_wrap = FlexWrap.Wrap
flex_wrap_reverse layout.flex_wrap = FlexWrap.WrapReverse

Splitting space

These size children along their parent's main axis. See Splitting space.

Function Description
grow(n: float) -> Style Take n shares of the free space along the parent's main axis (flex_grow).
shrink(n: float) -> Style Give up n shares of the overflow along the parent's main axis when the children don't fit (flex_shrink).
length(n: int) -> Style Take exactly n cells along the parent's main axis, whatever the content (ratatui's Length).
percentage(p: float) -> Style Take p percent of the parent's main axis, whatever the content (ratatui's Percentage).
ratio(numerator: int, denominator: int) -> Style Take numerator / denominator of the parent's main axis, whatever the content (ratatui's Ratio).
fill(n: float = 1) -> Style Share the parent's free main-axis space in proportion to n, whatever the content (ratatui's Fill).

Alignment

justify_children_* distributes children along the main axis, align_children_* places them on the cross axis, and align_self_* overrides that for one child. justify_items_* and justify_self_* place grid items within their cells along the row. The center and end forms are safe: content that doesn't fit overflows past the end edge only. The _unsafe forms overflow both edges. See Alignment and distribution.

Utility Sets
justify_children_start layout.justify_content = AlignContent.Start
justify_children_center layout.justify_content = AlignContent.SafeCenter
justify_children_end layout.justify_content = AlignContent.SafeEnd
justify_children_space_between layout.justify_content = AlignContent.SpaceBetween
justify_children_space_around layout.justify_content = AlignContent.SpaceAround
justify_children_space_evenly layout.justify_content = AlignContent.SpaceEvenly
justify_children_center_unsafe layout.justify_content = AlignContent.Center
justify_children_end_unsafe layout.justify_content = AlignContent.End
align_children_start layout.align_items = AlignItems.Start
align_children_center layout.align_items = AlignItems.SafeCenter
align_children_end layout.align_items = AlignItems.SafeEnd
align_children_stretch layout.align_items = AlignItems.Stretch
align_children_center_unsafe layout.align_items = AlignItems.Center
align_children_end_unsafe layout.align_items = AlignItems.End
align_self_start layout.align_self = AlignItems.Start
align_self_center layout.align_self = AlignItems.SafeCenter
align_self_end layout.align_self = AlignItems.SafeEnd
align_self_stretch layout.align_self = AlignItems.Stretch
align_self_center_unsafe layout.align_self = AlignItems.Center
align_self_end_unsafe layout.align_self = AlignItems.End
justify_items_start layout.justify_items = AlignItems.Start
justify_items_center layout.justify_items = AlignItems.SafeCenter
justify_items_end layout.justify_items = AlignItems.SafeEnd
justify_items_stretch layout.justify_items = AlignItems.Stretch
justify_items_center_unsafe layout.justify_items = AlignItems.Center
justify_items_end_unsafe layout.justify_items = AlignItems.End
justify_self_start layout.justify_self = AlignItems.Start
justify_self_center layout.justify_self = AlignItems.SafeCenter
justify_self_end layout.justify_self = AlignItems.SafeEnd
justify_self_stretch layout.justify_self = AlignItems.Stretch
justify_self_center_unsafe layout.justify_self = AlignItems.Center
justify_self_end_unsafe layout.justify_self = AlignItems.End
center_children layout.align_items = AlignItems.SafeCenter
layout.justify_content = AlignContent.SafeCenter

Sizing

See Sizing one box.

Utility Sets
content_box layout.box_sizing = BoxSizing.ContentBox
border_box layout.box_sizing = BoxSizing.BorderBox
min_content_width layout.size_width = MinContent()
max_content_width layout.size_width = MaxContent()
fit_content_width layout.size_width = FitContentKeyword()
stretch_width layout.size_width = Stretch()
min_content_height layout.size_height = MinContent()
max_content_height layout.size_height = MaxContent()
fit_content_height layout.size_height = FitContentKeyword()
stretch_height layout.size_height = Stretch()
full_width layout.size_width = Stretch()
full_height layout.size_height = Stretch()
full layout.size_height = Stretch()
layout.size_width = Stretch()
Function Description
width(n: int) -> Style Make the box n cells wide.
height(n: int) -> Style Make the box n cells tall.
size(w: int, h: int) -> Style Make the box w cells wide and h cells tall.
min_width(n: int) -> Style Keep the box at least n cells wide.
min_height(n: int) -> Style Keep the box at least n cells tall.
max_width(n: int) -> Style Keep the box at most n cells wide.
max_height(n: int) -> Style Keep the box at most n cells tall.
aspect_ratio(ratio: float) -> Style Keep the box's width divided by its height at ratio, so either one sets the other.

Spacing

See Gap, margin and padding.

Utility Sets
margin_auto layout.margin_bottom = Auto()
layout.margin_left = Auto()
layout.margin_right = Auto()
layout.margin_top = Auto()
margin_x_auto layout.margin_left = Auto()
layout.margin_right = Auto()
margin_y_auto layout.margin_bottom = Auto()
layout.margin_top = Auto()
margin_top_auto layout.margin_top = Auto()
margin_bottom_auto layout.margin_bottom = Auto()
margin_left_auto layout.margin_left = Auto()
margin_right_auto layout.margin_right = Auto()
Function Description
margin_top(n: int) -> Style Put n cells of margin above the box.
margin_bottom(n: int) -> Style Put n cells of margin below the box.
margin_left(n: int) -> Style Put n cells of margin left of the box.
margin_right(n: int) -> Style Put n cells of margin right of the box.
margin_x(n: int) -> Style Put n cells of margin left and right of the box.
margin_y(n: int) -> Style Put n cells of margin above and below the box.
margin(n: int) -> Style Put n cells of margin on all four sides of the box.
margin_sides(top: int, right: int, bottom: int, left: int) -> Style Put margin on each side of the box separately, in the order of CSS's four-value margin.
gap_width(n: int) -> Style Put n cells between children placed side by side.
gap_height(n: int) -> Style Put n cells between children placed one above another.
gap(n: int) -> Style Put n cells between children in both directions.
pad(n: int) -> Style Put n cells of padding inside the border on all four sides.
pad_x(n: int) -> Style Put n cells of padding inside the border on the left and right.
pad_y(n: int) -> Style Put n cells of padding inside the border on the top and bottom.
pad_top(n: int) -> Style Put n cells of padding inside the border on the top.
pad_bottom(n: int) -> Style Put n cells of padding inside the border on the bottom.
pad_left(n: int) -> Style Put n cells of padding inside the border on the left.
pad_right(n: int) -> Style Put n cells of padding inside the border on the right.
pad_sides(top: int, right: int, bottom: int, left: int) -> Style Put padding inside the border on each side separately, in the order of CSS's four-value padding.

Borders

A side is drawn where its border width is 1, and each width utility has a _0 form that takes its sides away. See Borders on some sides.

Utility Sets
border layout.border_bottom = Length(1)
layout.border_left = Length(1)
layout.border_right = Length(1)
layout.border_top = Length(1)
border_top layout.border_top = Length(1)
border_bottom layout.border_bottom = Length(1)
border_left layout.border_left = Length(1)
border_right layout.border_right = Length(1)
border_x layout.border_left = Length(1)
layout.border_right = Length(1)
border_y layout.border_bottom = Length(1)
layout.border_top = Length(1)
border_0 layout.border_bottom = Length(0)
layout.border_left = Length(0)
layout.border_right = Length(0)
layout.border_top = Length(0)
border_top_0 layout.border_top = Length(0)
border_bottom_0 layout.border_bottom = Length(0)
border_left_0 layout.border_left = Length(0)
border_right_0 layout.border_right = Length(0)
border_x_0 layout.border_left = Length(0)
layout.border_right = Length(0)
border_y_0 layout.border_bottom = Length(0)
layout.border_top = Length(0)
border_collapse layout.gap_height = Length(-1)
layout.gap_width = Length(-1)
Function Description
border_contract(n: int) -> Style Stop each border edge n cells short at an end next to a side that isn't drawn.
border_sides(sides: frozenset[Side]) -> Style Draw the border on exactly the given sides.

counterweight.styles.utilities.Side module-attribute

Side = Literal['top', 'bottom', 'left', 'right']

One side of a box.

Border kinds

The border kind only chooses the characters, and draws nothing without a border width. border_none removes the border along with its space. Every other kind is drawn below, each around its own name:

KINDS: tuple[tuple[str, Style], ...] = (
    ("border_light", border_light),
    ("border_lightrounded", border_lightrounded),
    ("border_lightangled", border_lightangled),
    ("border_heavy", border_heavy),
    ("border_double", border_double),
    ("border_thick", border_thick),
    ("border_mcgugan", border_mcgugan),
    ("border_lightshade", border_lightshade),
    ("border_mediumshade", border_mediumshade),
    ("border_heavyshade", border_heavyshade),
    ("border_star", border_star),
)


@component
def gallery() -> Div:
    return Div(
        style=display_grid | grid_template_columns(fr(1), fr(1), fr(1)) | gap(1),
        children=tuple(Text(style=border | kind | pad(1) | text_justify_center, content=name) for name, kind in KINDS),
    )

Every border kind

┌──────────────────────┐ ╭──────────────────────╮ /▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔╲
│                      │ │                      │ ▏                      ▕
│     border_light     │ │  border_lightrounded │ ▏  border_lightangled  ▕
│                      │ │                      │ ▏                      ▕
└──────────────────────┘ ╰──────────────────────╯ ╲▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁/

┏━━━━━━━━━━━━━━━━━━━━━━┓ ╔══════════════════════╗ ▛▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▜
┃                      ┃ ║                      ║ ▌                      ▐
┃     border_heavy     ┃ ║     border_double    ║ ▌     border_thick     ▐
┃                      ┃ ║                      ║ ▌                      ▐
┗━━━━━━━━━━━━━━━━━━━━━━┛ ╚══════════════════════╝ ▙▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▟

 ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁  ░░░░░░░░░░░░░░░░░░░░░░░░ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
▕                      ▏ ░                      ░ ▒                      ▒
▕    border_mcgugan    ▏ ░   border_lightshade  ░ ▒  border_mediumshade  ▒
▕                      ▏ ░                      ░ ▒                      ▒
 ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔  ░░░░░░░░░░░░░░░░░░░░░░░░ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒

▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ************************                         
▓                      ▓ *                      *                         
▓   border_heavyshade  ▓ *      border_star     *                         
▓                      ▓ *                      *                         
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ************************                         

The light, rounded, heavy and double kinds use box-drawing characters, which border healing joins where borders meet. The rest don't join, and draw their edges with block elements, shades, slashes or asterisks.

Utility Sets
border_none border_kind = None
border_light border_kind = BorderKind.Light
border_lightrounded border_kind = BorderKind.LightRounded
border_lightangled border_kind = BorderKind.LightAngled
border_heavy border_kind = BorderKind.Heavy
border_double border_kind = BorderKind.Double
border_thick border_kind = BorderKind.Thick
border_mcgugan border_kind = BorderKind.McGugan
border_lightshade border_kind = BorderKind.LightShade
border_mediumshade border_kind = BorderKind.MediumShade
border_heavyshade border_kind = BorderKind.HeavyShade
border_star border_kind = BorderKind.Star

Display and grids

display_none hides a box and everything in it: they take no space and aren't drawn. See Grids and wrapping for the grid utilities.

Utility Sets
display_flex layout.display = Display.Flex
display_block layout.display = Display.Block
display_grid layout.display = Display.Grid
display_none layout.display = Display.Nil
grid_auto_flow_row layout.grid_auto_flow = GridAutoFlow.Row
grid_auto_flow_column layout.grid_auto_flow = GridAutoFlow.Column
grid_auto_flow_row_dense layout.grid_auto_flow = GridAutoFlow.RowDense
grid_auto_flow_column_dense layout.grid_auto_flow = GridAutoFlow.ColumnDense
Function Description
fr(n: float = 1) -> waxy.Minmax A grid track taking n shares of the free space, whatever the content (minmax(0, n fr)).
span(n: int) -> waxy.GridSpan A grid placement spanning n tracks, for grid_row and grid_column.
grid_template_rows(*tracks: waxy.GridTrackValue | int) -> Style Define the grid's rows, one track each, with an int meaning that many cells.
grid_template_columns(*tracks: waxy.GridTrackValue | int) -> Style Define the grid's columns, one track each, with an int meaning that many cells.
grid_row(start: waxy.GridPlacementValue | int | None = None, end: waxy.GridPlacementValue | int | None = None) -> Style Place a grid item between row lines start and end, with an int meaning that line.
grid_column(start: waxy.GridPlacementValue | int | None = None, end: waxy.GridPlacementValue | int | None = None) -> Style Place a grid item between column lines start and end, with an int meaning that line.

Positioning and layering

See Layering. The inset_* utilities with a center axis, such as inset_bottom_center, center a box on that axis only in a parent that centers its children, such as with center_children. To center a box in any parent, see A dialog centered over the app.

Utility Sets
inset_top_left layout.inset_left = Length(0)
layout.inset_top = Length(0)
layout.position = Position.Absolute
inset_top_center layout.inset_left = Auto()
layout.inset_right = Auto()
layout.inset_top = Length(0)
layout.position = Position.Absolute
inset_top_right layout.inset_right = Length(0)
layout.inset_top = Length(0)
layout.position = Position.Absolute
inset_center_left layout.inset_bottom = Auto()
layout.inset_left = Length(0)
layout.inset_top = Auto()
layout.position = Position.Absolute
inset_center_center layout.inset_bottom = Auto()
layout.inset_left = Auto()
layout.inset_right = Auto()
layout.inset_top = Auto()
layout.position = Position.Absolute
inset_center_right layout.inset_bottom = Auto()
layout.inset_right = Length(0)
layout.inset_top = Auto()
layout.position = Position.Absolute
inset_bottom_left layout.inset_bottom = Length(0)
layout.inset_left = Length(0)
layout.position = Position.Absolute
inset_bottom_center layout.inset_bottom = Length(0)
layout.inset_left = Auto()
layout.inset_right = Auto()
layout.position = Position.Absolute
inset_bottom_right layout.inset_bottom = Length(0)
layout.inset_right = Length(0)
layout.position = Position.Absolute
position_relative layout.position = Position.Relative
position_absolute layout.position = Position.Absolute
Function Description
inset_top(n: int) -> Style Inset a positioned box n cells from the top.
inset_bottom(n: int) -> Style Inset a positioned box n cells from the bottom.
inset_left(n: int) -> Style Inset a positioned box n cells from the left.
inset_right(n: int) -> Style Inset a positioned box n cells from the right.
inset_x(n: int) -> Style Inset a positioned box n cells from the left and right.
inset_y(n: int) -> Style Inset a positioned box n cells from the top and bottom.
inset(n: int) -> Style Inset a positioned box n cells from all four sides.
inset_sides(top: int, right: int, bottom: int, left: int) -> Style Inset a positioned box from each side separately, in the order of CSS's four-value inset.
z(z: int = 0) -> Style Draw the box and its descendants as one layer at z among the boxes of the stacking context it belongs to, where the higher z is drawn on top, and make it a stacking context for its descendants' own z.

Overflow, clipping and scrolling

overflow_hidden, overflow_clip and overflow_scroll clip a box's children (and a Text's own lines) to its padding box, on both axes or, with _x or _y, on one, and overflow_scroll makes the box a scroll container there. clip_to_border lets a child, such as a border title, draw on its parent's border instead, and clip_to_screen lets one, such as a dropdown, escape every clip above it. See Clipping.

overflow_anchor_none turns off scroll anchoring, and stick_to_end makes a scroll container follow its end, on both axes or, with _x or _y, on one; unstick undoes it.

Utility Sets
overflow_visible layout.overflow_x = Overflow.Visible
layout.overflow_y = Overflow.Visible
overflow_x_visible layout.overflow_x = Overflow.Visible
overflow_y_visible layout.overflow_y = Overflow.Visible
overflow_hidden layout.overflow_x = Overflow.Hidden
layout.overflow_y = Overflow.Hidden
overflow_x_hidden layout.overflow_x = Overflow.Hidden
overflow_y_hidden layout.overflow_y = Overflow.Hidden
overflow_clip layout.overflow_x = Overflow.Clip
layout.overflow_y = Overflow.Clip
overflow_x_clip layout.overflow_x = Overflow.Clip
overflow_y_clip layout.overflow_y = Overflow.Clip
overflow_scroll layout.overflow_x = Overflow.Scroll
layout.overflow_y = Overflow.Scroll
overflow_x_scroll layout.overflow_x = Overflow.Scroll
overflow_y_scroll layout.overflow_y = Overflow.Scroll
clip_to_padding clip_to = 'padding'
clip_to_border clip_to = 'border'
clip_to_screen clip_to = 'screen'
overflow_anchor_auto overflow_anchor = 'auto'
overflow_anchor_none overflow_anchor = 'none'
stick_to_end stick_to_end_x = True
stick_to_end_y = True
stick_to_end_x stick_to_end_x = True
stick_to_end_y stick_to_end_y = True
unstick stick_to_end_x = False
stick_to_end_y = False
unstick_x stick_to_end_x = False
unstick_y stick_to_end_y = False

Text

See Text wrapping, Ending a line with …, and Text in layout.

Utility Sets
text_justify_left text_justify = 'left'
text_justify_center text_justify = 'center'
text_justify_right text_justify = 'right'
text_wrap_none text_wrap = 'none'
text_wrap_stable text_wrap = 'stable'
text_wrap_pretty text_wrap = 'pretty'
text_wrap_balance text_wrap = 'balance'
text_overflow_clip text_overflow = 'clip'
text_overflow_ellipsis text_overflow = 'ellipsis'