Skip to content
TYPO3Soul Design System
0.1.0-dev one accent · two modes · no shadows

A system, not a stylesheet

Tokens, a class layer and the elements over it — one vocabulary, whether a surface runs JavaScript or is rendered by PHP. Every rule it holds is shown on a card generated from the component that holds it.

audience 01

Product designer

Starting points to open, tokens to draw against, and a specimen for every rule — so a decision is looked up rather than remembered.

audience 02

Interface developer

Custom elements that need no build step and no framework. Light DOM, so the page around them styles them like anything else.

audience 03

Backend developer

The same class names a template writes by hand. Neither layer is a fallback for the other, and both are checked against the same file.

What it is made of

Four layers, and each of them is worth having on its own. A surface that takes only the tokens still cannot invent a colour; one that takes only the classes still gets both modes.

Layer Ships as Read by
tokens tokens.css — custom properties every layer above it, and a design tool
classes styles.css a Twig or Fluid template, by hand
elements soul.js — light DOM, no build a surface that runs JavaScript
specimens generated cards the guidelines, and the pane a design opens in

Three components in full

One per plane: a block the machine writes, the navigation beside a page, and the navigation above it. Each is documented from the element that renders it.

sds-code

A fenced block, its head and its copy button. It highlights what it is given rather than leaving that to the page — fourteen grammars, one of them TYPO3’s own, and a caption where a renderer has one to place.

elementclass layer14 grammars
Property Required Meaning
lang no The fence’s language. Sets the head and picks the grammar.
caption no What the block is, in a sentence, above the frame.
copy no The copy button. It copies what the block says, never its chrome.
source no The block as text, where the caller holds the source rather than markup.
html
<sds-code code-lang="bash" caption="Install" copy>
  <code>composer require typo3/soul-design-system</code>
</sds-code>

sds-nav-rail

The tool rail: a flat list, or one long enough to need sections. A section is a `details`, so it folds before any script has run and a closed rail is a few lines rather than a screen of them.

elementclass layerworks unscripted
Property Required Meaning
items yes Labels, or entries with an href, an icon, or a group of their own.
active no Which item is current. Pressing one moves it and says so.
open no Per group. A group holding the current item opens regardless.
html
<sds-nav-rail active="1" items='[
  "overview",
  { "label": "tools", "items": ["typo3_icon_lookup"] }
]'></sds-nav-rail>

sds-nav-main

The bar at the top of a page, and what it does as the page runs out. A row while there is room; one button and one drawer holding the field, the sections and the page rail when there is not — and which of the two is measured, not declared at a breakpoint somebody picked for one page.

elementclass layermeasures itself
Property Required Meaning
product yes The name in the lockup, with brand and signet where there are two halves.
items no The sections of the site, or the links a server wrote between the tags.
rail no The id of the page rail, which hangs under its own section in the drawer once it has no column.
html
<sds-nav-main product="Soul" signet="signet.svg" search items='[
  { "label": "overview", "href": "#overview" }
]'></sds-nav-main>

Where a rule comes from

Four places, and every one of them is a file rather than a habit.

source 01
The tokens file
One declaration carries both modes. Nothing below it names a colour, so a surface cannot be light-only by accident.
source 02
The component
A card ships the markup its element renders, from the same function. The documentation cannot drift, because there is nothing for it to drift from.
source 03
The guidelines
Written pages, drawn from the artwork files themselves — the construction, the sizes and the clear space are measured, not described.
source 04
The checks
Headers, classes, refs, fit, cards and types, on every change. A rule nothing checks is a preference somebody wrote down.

How a specimen gets made

The documentation is generated from the components, in four steps that run on every change.

step 01

A story is written

The component, with the properties it is being shown at. Nothing is hand-built beside it — a specimen that rebuilds the markup documents the rebuild.

step 02

The card is rendered

Server-side, to flat HTML at the size it declares, with every element replaced by what it produced.

step 03

The pane opens it

With styles.css and no JavaScript at all, which is the state that proves the class layer stands on its own.

step 04

The diff catches the rest

A card that moved is a picture that changed, and it is reviewed as one.

What is asked before it is adopted

Three of them, folded: a page that argues has to answer these, and a reader who has none of them is already at the install step.

Do we have to use the web components?
No. The class layer is the contract and it is the whole vocabulary — the elements are how a page that runs JavaScript gets that markup without writing it out. A page that renders on a server keeps the classes and loses nothing.
What happens to our own stylesheet?
It shrinks to what is genuinely yours. Anything you find yourself declaring twice is a gap in a component, and closing it there is the whole arrangement — a system everybody patches locally is a system nobody can change centrally.
Which framework does it need?
None. Two files, no build step, and nothing about the page it is on — the elements register themselves and the tokens are custom properties.

Install

Two files, and nothing to configure. The elements register themselves and the classes are already in the stylesheet — there is no build step to add and no framework to be on.

Install
bash
# one command, and the client finds it
$ composer require typo3/soul-design-system
 linked two files into public/assets

Pin a version where you depend on it. The class layer is the contract; the elements are how a page that runs JavaScript gets it without writing the markup out.