Skip to content

CSS Engine & Attribute Specification ​

This document provides the formal specification of the CSS styling engine implemented in RTXUI, defining value grammar, cascade and specificity rules, box-model semantics, and the exhaustive property reference.


1. Engine Formal Grammar ​

RTXUI implements an inline stylesheet parser and property resolver operating directly over terminal character cells.

ebnf
Declaration      ::= PropertyName ':' Value ('!important')? ';'
PropertyName     ::= [a-z-]+ | '--' [a-z0-9-]+
Value            ::= Token (Whitespace Token)*

Length           ::= Integer | Percentage | Fractional | Viewport | 'auto' | CalcExpr | MinMaxExpr
Integer          ::= [-+]? [0-9]+
Percentage       ::= [-+]? [0-9]+ ('.' [0-9]+)? '%'
Fractional       ::= [0-9]+ ('.' [0-9]+)? 'fr'
Viewport         ::= [0-9]+ ('.' [0-9]+)? ('vh' | 'vw')
Color            ::= HexColor | RgbColor | HslColor | ColorKeyword | ColorTransform

HexColor         ::= '#' ([0-9a-fA-F]{3} | [0-9a-fA-F]{4} | [0-9a-fA-F]{6} | [0-9a-fA-F]{8})
RgbColor         ::= ('rgb(' | 'rgba(') Number ',' Number ',' Number (',' Alpha)? ')'
                   | ('rgb(' | 'rgba(') Number Number Number ('/' Alpha)? ')'
HslColor         ::= ('hsl(' | 'hsla(') Angle (',' | Whitespace) Percentage (',' | Whitespace) Percentage (('/' | ',') Alpha)? ')'
ColorTransform   ::= ('lighten(' | 'darken(' | 'alpha(') (Percentage | Number) ')'
ColorKeyword     ::= 'transparent' | 'orange' | 'red' | 'white' | 'blue' | 'yellow' | 'green' | 'lime' | 'black' | 'gray' | 'grey' | 'cyan' | 'aqua' | 'magenta' | 'fuchsia' | 'silver' | 'maroon' | 'purple' | 'olive' | 'navy' | 'teal'

Coordinate & Dimensional Model ​

  • Grid Unit: 1 unit = 1 terminal character cell. vh and vw are hundredths of the terminal's height and width, rounded down to cells. Other units (px, em, rem, ...) are reported and ignored.
  • Physical Cell Aspect Ratio: Terminal cells are approximately 1:2 (width:height). An aspect ratio of 2 / 1 produces an approximately square visual block.
  • Default Box Model: Unlike web browsers which default to content-box, RTXUI defaults to border-box (box-sizing: border-box). Declared width and height define the outer dimensions including padding and borders.

2. Cascade, Inheritance & Specificity ​

2.1 Specificity Vector (A, B, C) ​

Selector precedence is determined by a 3-component specificity vector (A, B, C):

  1. $A$ (ID Component): Count of ID selectors (#id).
  2. $B$ (Class & Pseudo Component): Count of class selectors (.class), attribute selectors ([attr]), and pseudo-classes (:hover, :focus, :active, :checked, :disabled, :first-child, etc.).
  3. $C$ (Type Component): Count of element type selectors (div, button, span).

Note: Pseudo-elements (::part(...)) participate in target isolation rather than global specificity weighting. :is(X) counts as the entry of $X$ that matched and :where(X) counts nothing, as in CSS. Other functional pseudo-classes (:not(X), :has(X), :nth-child(...)) count as a single pseudo-class, whatever their argument; CSS would count the most specific selector in $X$ instead.

2.2 Precedence Order (Descending) ​

  1. Declarations with !important (resolved in reverse cascade order).
  2. Inline element styles (style="...").
  3. Higher specificity vector (A, B, C) (evaluated lexicographically: $A_1 > A_2$, then $B_1 > B_2$, then $C_1 > C_2$).
  4. Source declaration order (later rules override earlier rules).
  5. Inherited values from parent elements (only properties marked as inherited).
  6. Engine initial property defaults.

3. Spacing, Sizing, and Box Model ​

margin: <length> | auto⧉ shorthandInitial: `0`. Shorthand margin width on all sides.
margin-top: <length> | autoInitial: `0`. Vertical space above the element.
margin-bottom: <length> | autoInitial: `0`. Vertical space below the element.
margin-left: <length> | autoInitial: `0`. Horizontal space to the left.
margin-right: <length> | autoInitial: `0`. Horizontal space to the right.
padding: <integer>⧉ shorthandInitial: `0`. Shorthand internal padding on all sides.
padding-top: <integer>Initial: `0`. Internal vertical padding at the top.
padding-bottom: <integer>Initial: `0`. Internal vertical padding at the bottom.
padding-left: <integer>Initial: `0`. Internal horizontal padding at the left.
padding-right: <integer>Initial: `0`. Internal horizontal padding at the right.
width: <length>✦ animatableInitial: `auto`. Constrains element layout width.
height: <length>✦ animatableInitial: `auto`. Constrains element layout height.
min-width: <length>Initial: `auto`. Minimum layout width constraint.
max-width: <length>Initial: `none`. Maximum layout width constraint.
min-height: <length>Initial: `auto`. Minimum layout height constraint.
max-height: <length>Initial: `none`. Maximum layout height constraint.
box-sizing: content-box | border-boxInitial: `border-box`. Whether width/height (and their min/max variants) describe the content box or the border box. Default is border-box, unlike web CSS.

Logical properties ​

A terminal writes left to right and top to bottom, so the logical properties map onto fixed sides: the inline axis is left (start) to right (end), the block axis top (start) to bottom (end). Each takes the values of the physical property it stands for.

LogicalPhysical
margin-inline / padding-inline / inset-inline (<start> <end>?)-left, -right (left, right)
margin-block / padding-block / inset-block (<start> <end>?)-top, -bottom (top, bottom)
margin-inline-start, -inline-end, -block-start, -block-end (also padding-, inset-)margin-left, -right, -top, -bottom
inline-size, min-inline-size, max-inline-sizewidth, min-width, max-width
block-size, min-block-size, max-block-sizeheight, min-height, max-height
border-inline, border-block (one value for both sides)border-left + border-right, border-top + border-bottom
border-inline-start, -inline-end, -block-start, -block-end (also -width, -color)the same side's border, width or color
border-inline-width, border-block-width, border-inline-color, border-block-color (<start> <end>?)both sides

The standard per-side longhands border-top-width … border-left-width and border-top-color … border-left-color are accepted too.

calc() Expressions ​

Length properties accept calc() expressions combining discrete cells and percentages:

css
.sidebar {
  width: calc(100% - 20);
}
.split {
  height: calc((100% - 1) / 2);
}

min(), max(), and clamp() ​

  • min(a, b): Evaluates to the smaller resolved length.
  • max(a, b): Evaluates to the larger resolved length.
  • clamp(min, preferred, max): Clamps preferred between lower and upper bounds.
css
.responsive-box {
  width: clamp(20, 50%, 80);
}

4. Borders and Frames ​

border: <border-style> || <color> || <integer>⧉ shorthandInitial: `none`. Shorthand to configure borders on all sides, its words in any order: `border: round red`. Without a style it draws `solid`; without a width it keeps the one set, or 1; without a color it keeps the one set. Resets each side's own style.
border-width: <integer>Initial: `0`. Border frame cell thickness on all sides.
border-top: <border-style> || <color> || <integer>Initial: `0`. The top border alone, its words in any order: `border-top: heavy blue`. A <border-style> keyword gives this side its own character set and a thickness of 1.
border-bottom: <border-style> || <color> || <integer>Initial: `0`. The bottom border alone, its words in any order: `border-bottom: heavy blue`. A <border-style> keyword gives this side its own character set and a thickness of 1.
border-left: <border-style> || <color> || <integer>Initial: `0`. The left border alone, its words in any order: `border-left: heavy blue`. A <border-style> keyword gives this side its own character set and a thickness of 1.
border-right: <border-style> || <color> || <integer>Initial: `0`. The right border alone, its words in any order: `border-right: heavy blue`. A <border-style> keyword gives this side its own character set and a thickness of 1.
border-style: <border-style>Initial: `none`. Character set mapping style of the frame, on every side.
border-top-style: <border-style>Initial: the `border-style`. Character set of the top side alone; a side with no thickness yet gets 1. Corners follow the left and right sides, or join a light side to a heavy or double one.
border-bottom-style: <border-style>Initial: the `border-style`. Character set of the bottom side alone; a side with no thickness yet gets 1. Corners follow the left and right sides, or join a light side to a heavy or double one.
border-left-style: <border-style>Initial: the `border-style`. Character set of the left side alone; a side with no thickness yet gets 1. Corners follow the left and right sides, or join a light side to a heavy or double one.
border-right-style: <border-style>Initial: the `border-style`. Character set of the right side alone; a side with no thickness yet gets 1. Corners follow the left and right sides, or join a light side to a heavy or double one.
border-color: <color>✦ animatableInitial: `currentcolor`. Color of all border frame lines.
border-color-top: <color>✦ animatableInitial: `currentcolor`. Color of the top border line.
border-color-bottom: <color>✦ animatableInitial: `currentcolor`. Color of the bottom border line.
border-color-left: <color>✦ animatableInitial: `currentcolor`. Color of the left border line.
border-color-right: <color>✦ animatableInitial: `currentcolor`. Color of the right border line.
border-collapse: separate | collapseInitial: `separate`. On a table: `collapse` draws the borders of neighbouring cells, and of the cells and the table, once, where they meet, joining the lines into the junction glyphs (`┬ ├ ┼ ┤ ┴`) of their style. Joins within one family: light (solid, rounded), heavy or double.
border-spacing: <integer> <integer>?Initial: `0`. On a table with separate borders: cells between neighbouring cells, and between the cells and the table's border, horizontally then vertically. One value sets both. (CSS's initial value is 2px; 0 suits a grid of cells.)
outline: [<border-style>] [<color>] [<integer>]⧉ shorthandInitial: `none`. A frame drawn one cell outside the border box, using the border-style glyphs (default `solid`), in any order. It takes no room: nothing moves, and it is drawn over the margins, neighbours and content around the element, after everything else. Always one cell thick, so a width only says whether there is one (`outline: 0` removes it). An inline element with an outline keeps a box of its own rather than flowing into its line's text. Suits focus rings, e.g. `button:focus { outline: round yellow; }`.
outline-style: <border-style>Initial: `none`. Glyph set of the outline, from the border styles below.
outline-color: <color>Initial: `currentcolor`. Color of the outline.
outline-offset: <integer>Initial: `0`. Cells between the border box and the outline; negative draws it inside the box.

4.1 Border Style Glyph Matrix ​

RTXUI supports 29 border style keywords mapping directly to Unicode box-drawing and block elements:

Style KeywordCanonical AliasVisual Glyphs / Behavior Description
nonehiddenNo border rendered; 0 cells allocated.
blank—Reserves 1 cell perimeter without drawing lines (background passes through).
ascii—Plain ASCII fallback: +, -, |.
solid—Standard light box-drawing lines: ┌, ─, ┐, │, └, ┘.
roundroundedCurved corner box-drawing lines: ╭, ─, ╮, │, ╰, ╯.
heavy—Bold / heavy stroke lines: ┏, ━, ┓, ┃, ┗, ┛.
thick—Full block sides (█) with half-block top and bottom (▀, ▄).
double—Double parallel lines: ╔, ═, ╗, ║, ╚, ╝.
double-horizontal—Double lines on horizontal axes; single line on vertical axes.
double-vertical—Double lines on vertical axes; single line on horizontal axes.
dashed—Light dashed stroke lines: ┌, ╌, ╎.
heavy-dashed—Heavy dashed stroke lines: ┏, ╍, ╏.
dotted—Light dotted stroke lines: ┌, ┈, ┊.
dotted-fine—Braille dots along the outer edge of each cell: ⡏, ⠉, ⢹, ⡇, ⣇, ⣀.
outset—Solid lines, top and left lighter, bottom and right darker: a raised box.
inset—Solid lines, top and left darker, bottom and right lighter: a sunken box.
outer—Half-cell block hugging outer cell edge (▀, ▄, ▌, ▐).
inner—Half-cell block hugging inner cell edge.
tall—Quarter-block vertical bars; eighth-block horizontal lines.
wide—Quarter-block vertical bars with inset horizontal lines.
panel—Tall border structure featuring a solid top bar for title integration.
hkey—Horizontal-only boundary lines on top and bottom.
vkey—Vertical-only boundary lines on left and right.
shade-light—25% stippled block fill (░).
shade-medium—50% stippled block fill (▒).
shade-dark—75% stippled block fill (▓).
shadow3dLight shading top/left; dark shading bottom/right (depth effect).
block—Full block vertical columns (█) with half-block horizontals.
Fullscreen Demo
cpp
// Copyright 2026 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
//
// Every border style: solid, double, dashed, round, tall, vkey and more,
// then the ways to combine them: a color in the shorthand, a style per side.
//
// Each tile names the style it draws, so this doubles as a lookup table.
#include <rtxui/rtxui.hpp>
#include <string>
#include <string_view>
#include <vector>

using namespace rtxui;

class BordersDemo : public Component<BordersDemo> {
 public:
  std::vector<std::string> styles = {
      "solid",
      "round",
      "double",
      "heavy",
      "dashed",
      "dotted",
      "dotted-fine",
      "ascii",
      "heavy-dashed",
      "double-horizontal",
      "double-vertical",
      "tall",
      "wide",
      "thick",
      "inner",
      "outer",
      "panel",
      "hkey",
      "vkey",
      "outset",
      "inset",
      "block",
      "shadow",
      "blank",
      "shade-light",
      "shade-medium",
      "shade-dark",
      "none",
  };
  std::vector<std::string> combinations = {
      "border: round red",
      "border: double green",
      "border: solid; border-top: heavy",
      "border: solid; border-bottom: double yellow",
      "border-left: heavy magenta",
      "border-top: solid; border-bottom: solid",
      "border: dashed; border-left-style: heavy; border-right-style: heavy",
      "border: inset cyan",
  };

  std::string_view view = R"html(
      <div class="card">
        <h1>Borders</h1>
        <p>Every value of the border property, each drawn on itself.</p>

        <div class="grid">
          <for each="{styles}" as="s">
            <div class="tile" style="border: {s};">{s}</div>
          </for>
        </div>

        <h2>Combined</h2>
        <div class="grid combinations">
          <for each="{combinations}" as="c">
            <div class="tile" style="{c}">{c}</div>
          </for>
        </div>
      </div>

      <style>
        self {
          display: flex;
          align-items: center;
          justify-content: center;
          width: 100%;
          color: rgb(230, 237, 243);
        }
        .card {
          border: tall;
          border-color: rgb(48, 54, 61);
          background-color: rgb(22, 27, 34);
          padding: 1 3;
          width: 92;
          max-height: 100%;
          overflow-y: scroll;
        }
        h1, h2 {
          color: rgb(88, 166, 255);
        }
        h2 {
          margin-top: 2;
        }
        p {
          color: rgb(139, 148, 158);
        }
        .grid {
          display: grid;
          grid-template-columns: repeat(4, 1fr);
          gap: 2 2;
        }
        .combinations {
          grid-template-columns: repeat(2, 1fr);
        }
        .tile {
          border-color: rgb(88, 166, 255);
          text-align: center;
          padding: 1;
        }
        .tile:hover {
          border-color: yellow;
          background-color:black;
        }
      </style>
    )html";

  BordersDemo() {
    Bind(styles);
    Bind(combinations);
  }
};

int main() {
  auto app = Ref<BordersDemo>::New();
  Screen screen(app);
  screen.Loop();
  return 0;
}

5. Typography and Coloring ​

content: <string> | attr(<name>) ... | none | normalInitial: `normal`. Only in a `::before` or `::after` rule: the text of the box generated inside the element, from quoted strings (with CSS escapes, e.g. `\25B6`) and attribute values, concatenated. `none` and `normal` generate no box. Elsewhere it is reported as a diagnostic. See [Generated Content](/guide/css/basics#generated-content-before-and-after).
color: <color>✦ animatable↓ inheritedInitial: `white`. Foreground text character color.
foreground-color: <color>✦ animatable↓ inheritedInitial: `white`. Alias for color.
background-color: <color>✦ animatableInitial: `transparent`. Background block container cell color.
background: <color> | none✦ animatable⧉ shorthandInitial: `transparent`. Shorthand for background-color, the only part a terminal can draw: a value with an image, position or size in it is reported as unsupported. `none` is `transparent`.
opacity: <number>✦ animatableInitial: `1.0`. Transparency value (0.0 for transparent to 1.0 for opaque).
text-align: left | right | center | justify↓ inheritedInitial: `left`. Horizontal alignment of inline text flows. justify widens space runs on soft-wrapped lines (never the last line or lines ended by an explicit newline).
white-space: normal | nowrap | pre | pre-wrap | pre-line | break-spaces↓ inheritedInitial: `normal`. nowrap/pre disable wrapping; pre-line collapses space runs while honoring newlines. Note: this engine preserves interior whitespace and newlines in all modes, so normal, pre-wrap, and break-spaces behave alike.
font-weight: bold | bolder | lighter | normal | <number>↓ inheritedInitial: `normal`. Text weight. bold/bolder/>=600 render bold; lighter/<=300 render with the terminal's dim attribute.
font-style: italic | oblique | normal↓ inheritedInitial: `normal`. Applies italic styling to text (rendered with the terminal's italic attribute).
text-decoration: underline | double-underline | overline | line-through | strikethrough | blink | none↓ inheritedInitial: `none`. Text decorations (can specify space-separated lists, e.g. `overline underline`). `overline` renders as SGR 53, which not every terminal implements; those that do not simply draw no line. `none` clears all of them.
text-transform: uppercase | lowercase | capitalize | none↓ inheritedInitial: `none`. Case transformation of text (ASCII letters; other characters pass through).
text-indent: <integer>↓ inheritedInitial: `0`. Cells the first line of a block is shifted right by, or left when negative: `padding-left: 2; text-indent: -2` hangs a bullet. Only the block's first line, and only when its text comes before any block child.
line-clamp: <integer> | noneInitial: `none`. Shows the first N lines of a block, the last one ending in `...` when text was cut, like text-overflow's. The block is as tall as the lines shown. Counts the lines of the text before any block child.
-webkit-line-clamp: <integer> | noneInitial: `none`. The same as line-clamp, under the name browsers still require. No `display: -webkit-box` is needed.
letter-spacing: <integer> | normal↓ inheritedInitial: `normal`. Blank cells inserted between characters. Whole cells only; negative values clamp to 0. Spaced words never wrap mid-word.
tab-size: <integer>↓ inheritedInitial: `8`. Cells between tab stops; 8 by default. A tab advances to the next multiple of this from the start of its line, counted in cells so a full-width glyph moves the stop by two. Tabs are expanded during layout and never handed to the terminal, so the engine's own column accounting is what decides where they land. Outside white-space: pre and pre-wrap a tab is collapsible whitespace and becomes a single space, as in CSS. 0 removes tabs entirely.
line-height: <integer> | normal↓ inheritedInitial: `normal`. Minimum rows each line box occupies (whole rows; values below 1 clamp to 1). Tall inline content can still grow a line further.
overflow-wrap: anywhere | break-word | normal↓ inheritedInitial: `anywhere`. How words longer than the line are handled. Unlike CSS the default is anywhere: break at the container edge. normal keeps the word intact and lets it overflow.
word-wrap: anywhere | break-word | normal↓ inheritedInitial: `anywhere`. Legacy alias for overflow-wrap.
word-break: normal | break-all↓ inheritedInitial: `normal`. break-all treats every character boundary as a break opportunity, wrapping immediately at the boundary of a full line instead of pushing an overflowing word whole to the next line (unlike overflow-wrap, a last-resort fallback for otherwise-unbreakable words).
text-overflow: clip | ellipsisInitial: `clip`. Behavior when text overflows its block container.
visibility: visible | hiddenInitial: `visible`. Controls element visibility. Hidden elements keep their layout size.
cursor: default | pointerInitial: `default`. Mouse pointer styling when hovering the element.
pointer-events: auto | none↓ inheritedInitial: `auto`. `none` lets the mouse through the element: clicks, hover, drags and the wheel go to what is under it, as for a decoration drawn over the interface. Inherited, so a child setting `auto` takes the mouse again.
user-select: auto | text | none | all↓ inheritedInitial: `auto`, the parent's value. What dragging the mouse selects and copies of the element's text: `text` selects it, `none` leaves it out (and a drag starting on it selects nothing), `all` selects the element whole as soon as the selection reaches into it, a click included. Also spelled `-webkit-user-select`. See [Selecting and Copying Text](/guide/typography#selecting-and-copying-text).
vertical-align: baseline | top | middle | bottom | text-top | text-bottomInitial: `baseline`. Where an inline-level box (inline-block, a button in a line of text) sits in its line: on the baseline, its last line of text level with the text beside it (its bottom row when it has no text in flow or clips its content), or at the top, middle or bottom of the line. `text-top`/`text-bottom` are top/bottom. On a table cell, moves the content to the top, middle or bottom of the row; `baseline` is top there.

Color Transforms ​

  • lighten(amount): Interpolates toward #ffffff in sRGB space.
  • darken(amount): Interpolates toward #000000 in sRGB space.
  • alpha(amount): Sets the alpha transparency channel to amount.

Translucent colors ​

A color with alpha blends with whatever is painted beneath it. Painted straight onto the screen, it blends with the terminal's background: RTXUI asks the terminal for that color on startup (OSC 11), uses it for the blending only, and still leaves the rest of the screen at the terminal's own background, so a translucent or themed terminal shows through. A terminal that does not answer gets the color unblended. Screen::SetBackgroundColor names the background instead, and paints it everywhere. See the translucent example.

currentColor ​

currentColor (any case) is accepted by color, border-color and its per-side longhands, outline-color and outline. A border or outline with it is drawn in the element's text color and follows it, through transitions too; color: currentColor takes the parent's color. Other properties, such as background-color, do not accept it and report it as unsupported.


6. Custom Properties (--* and var()) ​

Properties with a -- prefix declare custom variables. They inherit down the element hierarchy and resolve during style application.

css
self {
  --primary-color: rgb(59, 130, 246);
}
.header {
  color: var(--primary-color, white);
}
  • Fallback Semantics: If a variable is missing, var(--name, fallback) evaluates the fallback expression. Fallbacks may contain nested var() calls.
  • Substitution Limit: Recursive resolution is capped at 128 expansions to prevent cyclic reference hangs.

7. Flexbox Layout ​

display: none | block | inline | flex | grid | inline-block | inline-flex | inline-grid | flow-rootInitial: `inline`. Enables the flex/grid layout engine or hides elements.
flex-direction: row | column | row-reverse | column-reverseInitial: `row`. Main formatting axis direction.
flex-wrap: nowrap | wrap | wrap-reverseInitial: `nowrap`. Controls wrapping behavior of flex items.
flex-flow: <flex-direction> || <flex-wrap>⧉ shorthandInitial: `row nowrap`. Shorthand for flex-direction + flex-wrap, in either order. The one left out goes back to its initial value.
flex-grow: <number>✦ animatableInitial: `0`. Portion of free space item claims along main axis.
flex-shrink: <number>✦ animatableInitial: `1`. Factor determining how much item shrinks.
flex-basis: <length>Initial: `auto`. Initial size of flex item before free space is distributed.
flex: shorthand⧉ shorthandInitial: `0 1 auto`. Shorthand for flex-grow, flex-shrink, and flex-basis.
order: <integer>Initial: `0`. Lays a flex item out earlier or later than its document position. May be negative; items sharing a value keep document order.
justify-items: stretch | start | center | endInitial: `stretch`. Inline-axis alignment of items inside their grid cell.
justify-self: auto | stretch | start | center | endInitial: `auto`. Per-item override of justify-items.
place-items: <align-items> <justify-items>?⧉ shorthandInitial: `stretch`. Shorthand for align-items + justify-items.
place-self: <align-self> <justify-self>?⧉ shorthandInitial: `auto`. Shorthand for align-self + justify-self.
align-items: stretch | flex-start | flex-end | center | baselineInitial: `stretch`. Alignment of items along the cross axis.
align-self: auto | stretch | flex-start | flex-end | center | baselineInitial: `auto`. Alignment of individual flex item along the cross axis.
align-content: stretch (normal) | flex-start (start) | flex-end (end) | center | space-between | space-around | space-evenlyInitial: `stretch`. Alignment of flex lines in multi-line flex container, and of a grid's rows in its height: `stretch` grows the `auto` rows (also those inside `minmax()`) to fill it. `start` and `end` are accepted as aliases of `flex-start` and `flex-end`.
justify-content: normal (stretch) | flex-start (start) | flex-end (end) | center | space-between | space-around | space-evenlyInitial: `normal`. Alignment of flex items along the main axis, where `normal` is `flex-start`, and of a grid's columns in its width, where `normal` stretches the `auto` columns to fill it. `start` and `end` are accepted as aliases of `flex-start` and `flex-end`.
place-content: <align-content> <justify-content>?⧉ shorthandInitial: `normal`. Shorthand for align-content + justify-content. One value sets both axes.
gap: <length>⧉ shorthandInitial: `0`. Spacing between flex items.
row-gap: <length>Initial: `0`. Spacing between flex rows/lines.
column-gap: <length>Initial: `0`. Spacing between flex columns/items.

8. Grid Layout ​

grid-template-columns: list of <length> | [names]Initial: `none`. Defines the column tracks of the grid. Supports repeat(count, tracks), `minmax(min, max)` (`min` not `fr`), `repeat(auto-fill, tracks)` (as many as fit) and `repeat(auto-fit, tracks)` (the same, without the repeated tracks no item is in), and line names in brackets: `[full-start] 1fr [main-start] 3fr [main-end full-end]`. An `auto` track is as wide as its widest item; auto tracks share what is left when no `fr` track takes it. `max-content` is the width of the widest item unwrapped, `min-content` wrapped as much as it can be (to one cell, since text wraps anywhere unless `overflow-wrap: normal`), both also inside `minmax()`; `fit-content(length)` grows with its content up to `length`. In rows, an item is as tall wrapped as unwrapped, so `min-content` and `max-content` are its height, like `auto`; a row whose minimum is `auto` or a content keyword (`fit-content(length)`, `minmax(auto, length)`) stays as tall as its items past its maximum, except for a scroll container (`overflow` other than `visible`), which scrolls instead.
grid-template-rows: list of <length> | [names]Initial: `none`. Defines the row tracks of the grid, as grid-template-columns.
grid-template: none | <rows> / <columns> | areas⧉ shorthandInitial: `none`. Shorthand for grid-template-rows, grid-template-columns and grid-template-areas: either `rows / columns`, or the areas form, one quoted row of area names each optionally followed by its size, then optionally `/ columns`: `"head head" 1 "nav main" 1fr / 20 1fr`.
grid-auto-columns: list of <length> | autoInitial: `auto`. The size of the columns past the template, created by items placed past it or by `grid-auto-flow: column`. A list repeats.
grid-auto-rows: list of <length> | autoInitial: `auto`. The size of the rows past the template. A list repeats: `grid-auto-rows: 1 2` alternates.
grid-auto-flow: [ row | column ] || denseInitial: `row`. Whether auto-placed items fill the grid row by row, adding rows, or column by column, adding columns. `dense` fills the earliest hole that fits each item, so items may go out of order.
grid-template-areas: <string>+ | noneInitial: `none`. Names the grid's cells, one quoted string per row: `"head head" "side main"`. `.` leaves a cell unnamed. Rows must have as many cells, and each name must cover a rectangle; otherwise the declaration is reported and ignored. The areas also add explicit tracks: without grid-template-columns, their columns share the width.
grid-area: <line> [ / <line> ]{0,3}⧉ shorthandInitial: `auto`. row-start / column-start / row-end / column-end. An edge left out takes the name of the edge across from it when that is a name, and is auto otherwise, so `grid-area: head` is the area head on both axes.
grid-column: <line> [ / <line> ]?⧉ shorthandInitial: `auto`. Shorthand for grid-column-start and grid-column-end; the end, left out, is the start's name if it is a name, else auto. A <line> is `auto`, a line number (from 1; negative counts back from the end of the explicit grid), `span <integer>`, or a name: a line's name from the template, or an area's, which on a start edge is the line `<name>-start` and on an end edge `<name>-end`. `grid-column: 1 / -1` spans every column, `grid-column: span 2` two columns wherever the item lands, `grid-column: main` the columns of the area or lines named main. A name that names no line leaves the edge auto.
grid-column-start: <line>Initial: `auto`. The line the item starts at, or `span <integer>`.
grid-column-end: <line>Initial: `auto`. The line the item ends at, or `span <integer>`.
grid-row: <line> [ / <line> ]?⧉ shorthandInitial: `auto`. Shorthand for grid-row-start and grid-row-end, as grid-column.
grid-row-start: <line>Initial: `auto`. The row line the item starts at, or `span <integer>`.
grid-row-end: <line>Initial: `auto`. The row line the item ends at, or `span <integer>`.
grid-gap: <length>⧉ shorthandInitial: `0`. Alias for gap.
grid-row-gap: <length>Initial: `0`. Alias for row-gap.
grid-column-gap: <length>Initial: `0`. Alias for column-gap.

9. Scrolling & Overflow Management ​

overflow: visible | hidden | scroll | auto⧉ shorthandInitial: `visible`. Shorthand to configure horizontal & vertical overflow.
overflow-x: visible | hidden | scroll | autoInitial: `visible`. Horizontal layout overflow (visible, hidden, scroll).
overflow-y: visible | hidden | scroll | autoInitial: `visible`. Vertical layout overflow (visible, hidden, scroll).
scrollbar-width: auto | noneInitial: `auto`. none hides visual scrollbars while keeping list scrollable.
scrollbar-color: <color> <color>✦ animatableInitial: `auto auto`. Foreground (thumb) and background (track) colors of scrollbars.
scroll-speed: <integer>Initial: `1`. Shorthand scroll step speed multiplier.
scroll-speed-x: <integer>Initial: `1`. Horizontal scroll step distance.
scroll-speed-y: <integer>Initial: `1`. Vertical scroll step distance.
scroll-behavior: auto | smoothInitial: `auto`. How a scroll container brings into view what it is asked to show: the target of an anchor link, or an element focused from the keyboard. `smooth` glides there, `auto` jumps. The mouse wheel and the scrolling keys (arrows, PageUp/PageDown, Home/End) always scroll at once.

10. Positioning, Transitions & Animations ​

transition: property duration timing-function⧉ shorthandInitial: `none`. Shorthand (e.g. transition: background-color 0.2s linear). Easing keywords: linear, ease, ease-in, ease-out, ease-in-out, ease-in-sine, ease-out-sine, ease-in-out-sine, ease-in-quad, ease-out-quad, ease-in-out-quad, ease-in-cubic, ease-out-cubic, ease-in-quart, ease-out-quart, ease-in-quint, ease-out-quint, ease-in-expo, ease-out-expo, ease-in-circ, ease-out-circ, ease-in-back, ease-out-back, step-start, step-end, steps(n[, start | end | jump-none | jump-both]), cubic-bezier(x1, y1, x2, y2).
animation: name duration [timing-function] [delay] [iteration-count] [direction] [fill-mode] [play-state]⧉ shorthandInitial: `none`. Plays the `@keyframes` rule called name (e.g. animation: pulse 1s ease-in-out infinite alternate). Parts come in any order; the first time is the duration, the second the delay. Comma-separate several animations. The keyframes are looked up in the stylesheet of the component declaring the animation, like every other rule; an unknown name is reported as a diagnostic.
animation-name: <name># | noneInitial: `none`. The @keyframes to play. The number of names decides how many animations run; the other animation-* lists repeat to cover them. Changing any other animation property leaves a running animation where it is; only removing the name and adding it back restarts it.
animation-duration: <time>#Initial: `0s`. Length of one iteration, as `2s` or `150ms`.
animation-delay: <time>#Initial: `0s`. Wait before the first iteration. A negative delay starts the animation that far into it.
animation-timing-function: <easing>#Initial: `ease`. Easing applied between each pair of keyframes, from the transition easing keywords. A keyframe block may declare its own to ease the way to the next block.
animation-iteration-count: <number># | infiniteInitial: `1`. How many times to play; fractions stop part way. An infinite animation keeps the screen redrawing, but a headless run does not wait for it to settle.
animation-direction: normal | reverse | alternate | alternate-reverseInitial: `normal`. Whether iterations play forwards, backwards, or alternate between the two.
animation-fill-mode: none | forwards | backwards | bothInitial: `none`. forwards holds the last keyframe once done; backwards shows the first during the delay; both does both. With none the animated properties return to their own values.
animation-play-state: running | pausedInitial: `running`. Pauses an animation where it is; running it again resumes from there.

@keyframes ​

css
@keyframes pulse {
  from {
    opacity: 0.4;
  }
  50% {
    opacity: 1;
    animation-timing-function: ease-out;
  }
  to {
    opacity: 0.4;
  }
}

Blocks are selected by from (0%), to (100%) or a percentage, several at once when comma-separated. A property missing from the first or last block runs from, or to, the element's own value. Keyframes animate the properties transitions do: color, background-color, border-color and its per-side border-color-* longhands, opacity, flex-grow, flex-shrink, width, height, top, right, bottom, left, inset and translate. Any other declaration in a block is reported as a diagnostic.

position: static | relative | absolute | fixed | stickyInitial: `static`. Selects positioning flow model. An absolute/fixed box with an auto width or height sizes itself from its content, capped by the space available to it — it is free to be wider than the element it is anchored to, which is what lets a tooltip overhang a narrow trigger. Pinning both opposite edges (top and bottom, or left and right) stretches it between them instead, so inset: 0 fills the nearest positioned ancestor; auto margins on that axis opt back out, keeping the box content-sized and centering it between the edges.
inset: 1-4 <length> values✦ animatable⧉ shorthandInitial: `auto`. Shorthand setting top/right/bottom/left (same expansion as margin).
aspect-ratio: <w> / <h> | <number> | autoInitial: `auto`. Derives an element's auto dimension from whichever of width/height is definite: height-from-width in block, flex, and grid contexts (items and containers), and width-from-height in block contexts and on flex items/containers (grid containers only derive height from width). Ratios are in cells — terminal cells are ~2:1 tall, so 2 / 1 looks square. Content larger than the ratio overflows.
top: <length>✦ animatableInitial: `auto`. Offset relative to top boundary.
bottom: <length>✦ animatableInitial: `auto`. Offset relative to bottom boundary.
left: <length>✦ animatableInitial: `auto`. Offset relative to left boundary.
right: <length>✦ animatableInitial: `auto`. Offset relative to right boundary.
translate: <x> [<y>] | none✦ animatableInitial: `none`. Moves the box as painted and clicked, after layout: nothing around it moves. Each value is a length, a percentage of the box's own width or height, or calc() of both; `translate: calc(100% + 2)` takes a box just past its own right edge. A translated box paints above the in-flow boxes beside it, like a positioned one.
z-index: <integer> | autoInitial: `auto`. Determines rendering paint layers.

11. List Styling ​

list-style-type: disc | circle | square | decimal | noneInitial: `disc`. Sets the marker prefix style for list items (• , ○ , ■ , numbers, or none).
list-style: disc | circle | square | decimal | none⧉ shorthandInitial: `disc`. Shorthand configuration for list styling.