Experienced frontend developers already know the uncomfortable truth: UI complexity does not come from CSS syntax or framework choice. It comes from implicit responsibility. Who owns spacing. Who controls size. Who is allowed to style descendants. Who captures input. What happens when text grows. What breaks when layouts switch at a breakpoint.
Most UI systems rely on conventions, reviews, and experience to keep this under control. That works, until it doesn’t. Deep nesting, design system growth, accessibility requirements, theming, responsiveness, and motion all push the same weak spots.
This article proposes a different approach.
Not a framework. Not a CSS methodology. Not a component library.
A compositional model for UI, where layout, style, and interaction are treated as explicit contracts that can be reasoned about, composed safely, and eventually formalised.
N.B.: When we use the term Algebraic UI, we’re not referring to algebraic effects, UI state machines, or functional control flow.
We’re using “algebraic” in the structural sense: UI paradigms are treated as composable algebraic objects with explicit compatibility rules, identity elements, and substitution laws.
The core idea: UI as responsibility contracts
Instead of thinking in terms of HTML elements and CSS rules, we model UI as a tree of responsibility zones.
Each zone makes explicit promises:
- what it controls
- what it forbids
- what it expects from its parent
- what it guarantees to its children
Composition becomes safe when:
a child’s requirements are satisfied by its parent’s guarantees
This simple rule turns layout bugs into type errors.
Paradigms, not properties
A paradigm is a stable bundle of rules that govern responsibility.
Paradigms are not visual patterns.
They are laws.
Examples people already recognise intuitively:
- stack
- grid
- overlay
- modal
- card
- button
What changes here is that each paradigm is defined explicitly, not socially.
Concerns: the dimensions of responsibility
Instead of ad-hoc rules, each paradigm is defined as a vector over a small number of concerns. Each concern has a closed set of allowed values.
Layout concerns (example set)
- Flow: none | block | inline | axis(horizontal|vertical) | grid | overlay
- Spacing ownership: parent | child | shared | forbidden
- Spacing propagation: inherit | isolate | reset
- Sizing authority: intrinsic | constrained | imposed
- Margin emission: allowed | forbidden
- Boundary strength: transparent | soft | hard
- Text growth tolerance: flexible | bounded | fixed
- Adaptivity: static | adaptive | responsive
These do not describe how layout is implemented. They describe who is responsible.
Style as authority, not decoration
Style is not just colour and typography. Style is visual authority.
Style paradigms answer questions like:
- who may style whom
- how far styles propagate
- whether tokens may be overridden
- whether the cascade participates or is isolated
Style concerns (example set)
- Style scope: self | children | subtree
- Inheritance: inherit | block | explicit
- Token dependency: none | consume | override
- Visual authority: parent | component | shared
- Cascade participation: isolated | layered | global
- Reset behaviour: none | partial | full
Once these are explicit, subtree styling stops being an accident.
Interaction and animation as contracts
Interaction is not business logic. It is input and time responsibility.
Animation is not decoration. It is temporal state change.
Interaction and motion concerns (example set)
- Input capture: none | child | parent | exclusive
- Event propagation: bubble | capture | intercept | isolate
- Interaction ownership: component | container | shared
- Temporal authority: self | parent | external
- Interruptibility: non-interruptible | interruptible | reversible
- Reduced-motion sensitivity: insensitive | adaptive
This makes modals, sliders, drawers, and carousels first-class citizens instead of special cases.
Components vs layout paradigms
A crucial distinction:
- Layout paradigms organise children
- Component paradigms define a single interactive unit
A Stack and a Button are not competing abstractions. They are orthogonal.
A real component combines them:
- external contract: element-level
- internal implementation: layout paradigms sealed behind boundaries
This cleanly handles components that are both layout and element internally, such as sliders or tabs.
Schemes and themes: separating meaning from values
Design systems fit naturally once responsibilities are explicit.
- Schemes define semantic slots and proportions
- Themes assign concrete values
Typography, spacing scales, colour roles, motion curves all live here.
Paradigms never care about values. They care about tolerance.
A layout does not decide font size. It decides whether text growth is allowed to affect structure.
Accessibility as an invariant, not a feature
Accessibility is not a separate paradigm.
It is a set of constraints that must hold across layout, style, and interaction:
- focus must be reachable
- motion must be interruptible or adaptive
- contrast must meet thresholds
- text must remain readable under scaling
ARIA attributes and semantic tags become implementation details, not design crutches.
If the contracts hold, accessibility follows mechanically.
Responsive design as paradigm substitution
Breakpoints are not layout logic.
They are context signals.
Responsive behaviour becomes:
substitute paradigm A with paradigm B
when condition C holds
provided external contracts remain valid
Grid → Stack
Sidebar → Overlay drawer
Cluster → Flow
No half-states. No accidental overrides.
Why this is not a framework
This model does not prescribe:
- HTML structure
- CSS syntax
- JavaScript framework
It defines:
- contracts
- compatibility
- forbidden states
Frameworks can be built on top of it.
What this enables
- Mechanical validation of UI composition
- Deep nesting without fear
- Safe theming and scaling
- Predictable accessibility
- Refactoring without visual regressions
Most importantly, it turns UI from folklore into something we can reason about.
What comes next
This article describes the model informally. These are the next steps:
- define paradigms as algebraic objects, formally
- define compatibility
- define composition and substitution operators
- identify the most useful settings for key concerns and build a conceptual paradigm on top
- build a design system modelled after that
- build a tiny example application using the above




Top comments (0)