Arkitektur
TailwindPHP är en portning till 1:1. Kodbasen speglar TailwindCSSs egen struktur — samma filnamn, samma organisation — och isolerar delarna som inte kan porteras direkt (PHP har ingen Rust och ingen V8) under src/_tailwindphp/. Den här sidan går igenom kompileringspipelinen, källkodens struktur, lightningcss-omimplementeringen och konventionen för att dokumentera avvikelser.
Flödet
Generering av CSS sker i flera steg. Det finns inget separat byggsteg — varje anrop till tw::generate() kör hela pipelinen.
CSS input (@import "tailwindcss"; @theme { … })
│
▼
┌──────────────┐
│ Parse CSS │ css-parser.php → ast.php nodes
└──────┬───────┘
▼ design system (theme, utilities, variants)
┌──────────────┐
│ Scan content │ candidate.php — extract class names from HTML
└──────┬───────┘
▼ candidates
┌──────────────┐
│ Compile │ compile.php — candidate → AST, via design-system.php
└──────┬───────┘
▼ AST
┌──────────────┐
│ Optimize │ _tailwindphp/LightningCss.php — nesting, @media, calc()
└──────┬───────┘
▼
┌──────────────┐
│ Serialize │ ast.php toCss() (minified when requested)
└──────┬───────┘
▼
CSS output
Parsa. css-parser.php läser indata i CSS — @import, @theme, @utility, @layer och råa regler — till ett abstrakt syntaxträd med ast.php-noder (stilregler, at-regler, deklarationer). @import-direktiv för virtuella moduler (tailwindcss, tailwindcss/preflight, …) och filsökvägar löses och ersätts i detta steg.
Bygg designsystemet. theme.php löser temavärden (färger, avstånd, brytpunkter) från de parsade @theme-blocken och standardvärdena. design-system.php är det centrala registret som kopplar temat till uppslagningarna för verktyg och varianter i utilities.php och variants.php.
Skanna innehåll. candidate.php extraherar kandidater för klassnamn från det angivna innehållet (HTML, mallar) och delar upp varje kandidat i sina delar — basverktyg, varianter, modifierare, godtyckliga värden och flaggan important.
Kompilera. compile.php omvandlar varje kandidat till AST-noder genom att slå upp den i designsystemet och tillämpa dess varianter och modifierare. Kandidater som inte motsvarar ett verkligt verktyg tas bort.
Serialisera och optimera. ast.phps toCss() går igenom trädet (med hjälpfunktioner i walk.php) och genererar strängen CSS. Transformationerna motsvarande lightningcss i _tailwindphp/LightningCss.php tillämpas så att resultatet matchar det som TailwindCSS genererar efter sitt efterbehandlingssteg med Rust.
Minifiera. När minify är aktiverat genererar toCss() minifierad CSS under serialiseringen. _tailwindphp/CssMinifier.php hanterar den fristående strängpasseringen för tw::minify(). Se Cachelagring och minifiering.
Källkodens struktur
src/ speglar TailwindCSS. Den enda strukturella ändringen: TailwindCSSs utilities.ts har 6,000+ rader och delas därför upp i src/utilities/ med en fil per kategori för enklare underhåll.
src/
├── _tailwindphp/ # PHP-specific — NOT part of the TailwindCSS port
│ ├── LightningCss.php # CSS transforms (lightningcss Rust library equivalent)
│ ├── CssMinifier.php # CSS minification
│ └── lib/ # Companion library ports (TailwindPHP\Lib\*)
│ ├── clsx/ # clsx port
│ ├── tailwind-merge/ # tailwind-merge port
│ └── cva/ # CVA port
│
├── plugin/ # Plugin system
│ └── plugins/
│ ├── typography-plugin.php # @tailwindcss/typography port
│ └── forms-plugin.php # @tailwindcss/forms port
│
├── utilities/ # Split from TailwindCSS utilities.ts (one file per category)
│ ├── accessibility.php # sr-only, forced-colors
│ ├── backgrounds.php # bg-*, gradient-*, from-*, via-*, to-*
│ ├── borders.php # border-*, rounded-*, divide-*, outline-*
│ ├── effects.php # shadow-*, opacity-*, mix-blend-*
│ ├── filters.php # blur-*, brightness-*, contrast-*, …
│ ├── flexbox.php # flex-*, grid-*, gap-*, justify-*, align-*
│ ├── interactivity.php # cursor-*, scroll-*, touch-*, select-*
│ ├── layout.php # display, position, z-*, overflow-*, …
│ ├── masks.php # mask-linear-*, mask-radial-*, mask-conic-*
│ ├── sizing.php # w-*, h-*, min-*, max-*, size-*
│ ├── spacing.php # m-*, p-*, space-*
│ ├── svg.php # fill-*, stroke-*
│ ├── tables.php # border-collapse, table-layout
│ ├── transforms.php # translate-*, rotate-*, scale-*, skew-*
│ ├── transitions.php # transition-*, duration-*, ease-*, delay-*
│ └── typography.php # font-*, text-*, leading-*, tracking-*
│
├── utils/ # Helper functions (ported from utils/)
│
├── index.php # Main entry — compile(), cn(), variants(), merge(), join()
├── ast.php # AST nodes and toCss()
├── candidate.php # Candidate parsing (class name → parts)
├── compile.php # Candidate to CSS compilation
├── css-functions.php # theme(), --theme(), --spacing(), --alpha()
├── css-parser.php # CSS parsing
├── design-system.php # Central registry for utilities/variants
├── plugin.php # Plugin system (PluginInterface, PluginAPI, PluginManager)
├── theme.php # Theme value resolution
├── utilities.php # Utility registration and lookup
├── value-parser.php # CSS value parsing
├── variants.php # Variant handling (hover, focus, responsive, …)
└── walk.php # AST traversal
Motsvarigheten till lightningcss
TailwindCSS delegerar sin efterbehandling av CSS — nästling, hantering av mediefrågor och förenkling av värden — till lightningcss, en parser/transformerare/minifierare skriven i Rust. PHP kan inte läsa in ett Rust-bibliotek, så src/_tailwindphp/LightningCss.php implementerar på nytt de transformationer som TailwindPHP faktiskt använder. Resultatet blir identiskt byte för byte i de fall som testsviten omfattar.
Bekräftade transformationer omfattar:
| Transformation | Vad den gör |
|---|---|
| Utplattning av nästling | Löser &-selektorer med referensens :is(…)-regler och plattar till nästlade regler (handleNesting() i ast.php, en portning av TailwindCSS-passeringen); transformNesting konverterar den nästling som återstår under den första nivån med deklarationer till äldre syntax |
| Utplattning av villkorliga at-regler | Plattar till nästlade @media, @supports, @container och @starting-style på plats, bevarar källordningen och slår endast ihop direkt intilliggande syskon med identiska villkor |
| Deklarationsordning | Ordnar om deklarationer enligt lightningcss-kedjan för deklarationshantering, så att egenskaperna följer referensens ordning (reorderDeclarations) |
Förenkling av calc() |
Förenklar calc()-uttryck (simplifyCalcExpressions) |
| Borttagning av inledande nolla | 0.5 → .5 (normalizeLeadingZeros) |
| Mellanslag i transformationsfunktioner | Normaliserar mellanslag inuti transformationsfunktioner (normalizeTransformFunctions) |
| Normalisering av grid-värden | Lägger till mellanslag runt / i span-värden; omvandlar rena heltal till px för grid-template-* (normalizeGridValues) |
| Färgnormalisering | Normaliserar färgsyntax och utvärderar color-mix() till oklab() (normalizeColors, evaluateColorMix) |
| Citering av URL | url(./x.jpg) → url("./x.jpg") (normalizeUrlQuoting) |
| Leverantörsprefix | Prefixning motsvarande Autoprefixer (addVendorPrefixes) |
Den här filen ligger avsiktligt i karantän under _tailwindphp/ och är markerad @port-deviation:replacement — den står för ett externt beroende i stället för att porta källkod från TailwindCSS.
Markörer för portningsavvikelser
Varje implementeringsfil har @port-deviation:*-markörer i sitt docblock som anger var och varför PHP-implementationen avviker från originalet i TypeScript. Målet är att den som jämför PHP med källkoden i TailwindCSS aldrig ska behöva undra om en skillnad är avsiktlig.
| Markör | Betydelse |
|---|---|
@port-deviation:none |
Direkt portning av 1:1 utan betydande avvikelser |
@port-deviation:async |
PHP använder synkron kod i stället för async/await |
@port-deviation:storage |
Andra datastrukturer (array i PHP jämfört med Map/Set i JS) |
@port-deviation:types |
PHPDoc-anteckningar i stället för typer i TypeScript |
@port-deviation:sourcemaps |
Spårning av källkartor utelämnad |
@port-deviation:enum |
Konstanter i PHP i stället för enum-typer i TypeScript |
@port-deviation:errors |
Annat sätt att hantera fel |
@port-deviation:replacement |
PHP-implementation som ersätter ett externt bibliotek (e.g. lightningcss) |
@port-deviation:helper |
Hjälpfunktion specifik för PHP som saknas i originalet |
@port-deviation:performance |
Optimering specifik för PHP som bevarar identiska resultat |
@port-deviation:omitted |
Hela modulen/funktionen har inte porterats (utanför omfattningen) |
Se Prestanda och testning för information om @port-deviation:performance-markörerna och hur likvärdighet säkerställs.