Tailwind CSS

Style Lynx elements with Tailwind CSS utility classes. AngularLynx supports Tailwind CSS v3 through @lynx-js/tailwind-preset, which limits Tailwind's utilities to the CSS that Lynx supports.

Add Tailwind

npm create angular-lynx asks whether to add Tailwind, and adds it unless you say no. To add it to an existing app, run the schematic:

ng generate @blotch/angular-lynx:add-tailwind

It does three things:

  • Installs tailwindcss@3 and @lynx-js/tailwind-preset as dev dependencies.
  • Writes tailwind.config.ts with the Lynx preset.
  • Replaces src/styles.css (or src/styles.scss) with Tailwind's directives. Copy out any global styles you want to keep first.

There's nothing to add to angular.json. The build turns Tailwind on when it finds a tailwind.config.ts.

Set it up by hand

  1. Install Tailwind v3 and the preset:

    npm install -D tailwindcss@3 @lynx-js/tailwind-preset
  2. Create tailwind.config.ts in the project root:

    tailwind.config.ts
    import type { Config } from 'tailwindcss';
    import preset from '@lynx-js/tailwind-preset';
    
    const config: Config = {
      content: ['./src/**/*.{html,ts}'],
      presets: [preset],
    };
    
    export default config;
  3. Add the directives to your global stylesheet:

    src/styles.css
    @tailwind base;
    @tailwind utilities;

The schematic leaves out @tailwind components, whose rules Lynx can't fully parse.

Tailwind v3 only

The Lynx preset works with Tailwind v3. Tailwind v4 isn't supported, so don't install @tailwindcss/postcss or @tailwindcss/vite, which are v4 packages.

Use utility classes

src/app/counter.ts
import { Component, signal } from '@angular/core';
import { LYNX_ELEMENTS } from '@blotch/angular-lynx';

@Component({
  selector: 'app-counter',
  imports: [LYNX_ELEMENTS],
  template: `
    <view class="flex flex-col items-center gap-3 p-4">
      <text class="text-4xl font-bold text-slate-900">{{ count() }}</text>
      <view
        class="flex w-full justify-center rounded-lg bg-blue-600 p-4"
        (bindtap)="increment()"
      >
        <text class="font-semibold text-white">Add one</text>
      </view>
    </view>
  `,
})
export class Counter {
  readonly count = signal(0);

  increment(): void {
    this.count.update((n) => n + 1);
  }
}
  • Put text classes on the <text>. text-white on the blue <view> wouldn't color its label, because CSS doesn't inherit on Lynx. See Inheritance.
  • Rows need flex flex-row. Elements stack in a column by default, and flex-row alone does nothing.
  • Sizes run 12.5% smaller than on the web. Tailwind's scale uses rem, which is 14px on Lynx. For an exact size, use an arbitrary px value such as w-[44px].

Write classes in inline templates

Classes in

.html templates Tailwind only finds classes written in inline templates (template:) for now. Classes that appear only in a separate .html template get no CSS.

During ng build and ng serve, AngularLynx hands Tailwind the files your app bundles, in place of content. Those are your .ts files. An .html template is read by the Angular compiler, so Tailwind never sees it.

ng generate component makes an .html template by default. For components styled with Tailwind, generate an inline one:

ng generate component card --inline-template

To make that the default, set it in angular.json:

angular.json
{
  "projects": {
    "my-app": {
      "schematics": {
        "@schematics/angular:component": {
          "inlineTemplate": true
        }
      }
    }
  }
}

The schematic writes content: ['./src/**/*.ts']. Change it to ./src/**/*.{html,ts}, as in the manual setup, so editor tools that read content see your .html templates too.

Mix with component styles

Tailwind classes come from the global stylesheet, so they combine with a component's own styles:

src/app/badge.ts
import { Component } from '@angular/core';
import { LYNX_ELEMENTS } from '@blotch/angular-lynx';

@Component({
  selector: 'app-badge',
  imports: [LYNX_ELEMENTS],
  template: `
    <view class="app-badge self-start rounded-full bg-slate-800 px-3 py-1">
      <text class="text-xs text-white">New</text>
    </view>
  `,
  styles: `
    .app-badge {
      border-width: 1px;
      border-style: solid;
      border-color: #dd0031;
    }
  `,
})
export class Badge {}

Component styles aren't isolated on Lynx, so give their classes distinctive names, like app-badge. See Component styles.

What doesn't work

The preset drops utilities Lynx can't render. These are the gaps you'll notice first:

  • The hover:, focus:, sm:, md: and dark: variants don't work on a phone. Lynx has no :hover or :focus, and AngularLynx apps don't support @media. For dark mode, see Dark mode.
  • block, inline and inline-block have no effect. Lynx has no flow layout.
  • overflow-auto and overflow-scroll don't scroll a <view>. Use <scroll-view>.
  • uppercase, lowercase and capitalize do nothing. Lynx has no text-transform.

CSS on Lynx lists every CSS difference. The preset's support matrix lists every utility.

UI components

The UI components add semantic color utilities such as bg-background and text-foreground through their own Tailwind plugin. They switch colors when the page has a dark class. See Theming and Dark mode.