---
title: Building CSS
description: "Understand how labb scans component usage, prepares Tailwind sources, and builds the CSS for a Django project."
keywords: "labb build css, tailwind django labb, labb dev watcher, django-cotton tailwind"
---

The labb CLI reads component usage in your templates and prepares the CSS classes those components need.


## Why labb scans components

Tailwind scans templates for literal class names. It cannot infer the classes behind component props such as these.

```html
<c-lb.button variant="primary" size="lg">Click me</c-lb.button>
```

Tailwind cannot determine that `variant="primary"` needs `btn-primary` or that `size="lg"` needs `btn-lg`. Without a safelist, those classes would be absent from the generated CSS.

## Scan, prepare, and build

labb handles this in three stages.

### Scan templates

Run `labb scan` to find labb components in your templates.

```bash
labb scan
```

It does three things.

- Finds `<c-lb.component-name>` tags
- Reads their attributes and values
- Maps each value to classes from the component schema

The scan covers the following sources.

1. Local templates listed in `css.scan.templates`
2. `components` templates in subscribed [`css.packages`](/docs/guide/references/config-yaml/) groups

### Prepare the classes

For each component, the scanner maps its attributes to classes.

1. It identifies the component, such as `button`, `card`, or `modal`.
2. It reads attributes such as `variant="primary"` and `size="lg"`.
3. It applies the component schema.

    - `variant="primary"` → `btn-primary`
    - `size="lg"` → `btn-lg`
    - Base classes are always included (e.g., `btn`)

The generated safelist lives at `.labb/labb-component-classes.txt`. `.labb/` is gitignored.

```
/* Auto-generated by labb, do not edit */
/* Total classes: 15 */

btn
btn-primary
btn-lg
card
card-body
card-title
...
```

labb also writes `.labb/labb.css`. It brings together the safelist, raw utility sources from package `literals` groups, and inlined package CSS from `imports`. Keep one import in `input.css`.

```css
/* labb css - don't remove this line */
@import "../.labb/labb.css";
```

### Build the stylesheet

Run `labb build` to create the final CSS with Tailwind.

```bash
labb build
```

It regenerates labb’s generated CSS, reads your input stylesheet, and writes the optimised output.


## Run the commands

```bash
# Scan component usage
labb scan

# Build the CSS
labb build

# Or combine the two
labb build --scan
```

## Development workflow

During development, watch for changes.

```bash
# Rescan templates on change
labb scan --watch

# Rebuild CSS on change
labb build --watch

# Watch both
labb dev
```

<c-lb.alert variant="info" alertStyle="outline">
<span>`labb dev` runs `labb build -w -s`.</span>
</c-lb.alert>


## Example

For this template:

```html
<c-lb.button variant="primary" size="lg">Submit</c-lb.button>
<c-lb.card>
  <c-lb.card.body>
    <c-lb.card.title>Hello World</c-lb.card.title>
  </c-lb.card.body>
</c-lb.card>
```

The scanner adds these classes to the safelist.

```
btn
btn-primary
btn-lg
card
card-body
card-title
```


## Dynamic values

Some prop values are unknown until the page runs. The scanner includes every class that the prop can produce according to its schema.

```html
<c-lb.badge variant="$status:neutral">Active</c-lb.badge>   
<c-lb.badge :variant="user_variant">Active</c-lb.badge>      
<c-lb.badge variant="">Active</c-lb.badge>     
```

Each example keeps `badge-neutral`, `badge-primary`, `badge-success`, and the other valid variants in the built CSS. You do not need to safelist them by hand.

The scanner still needs a literal component and prop name. It can read `<c-lb.badge>` and look up `variant`, but cannot resolve `<c-component is="...">`. Safelist the required classes when the component name comes from runtime data.

## Safelisting

When the scanner cannot see a class, add it to `input.css`.

```css
@import "tailwindcss";
@source inline("btn-primary btn-secondary btn-lg btn-sm");
```

Keep custom safelists in `input.css`. labb regenerates `.labb/` on each build.

The <a href="https://tailwindcss.com/docs/detecting-classes-in-source-files#safelisting-specific-utilities" target="_blank">Tailwind safelisting documentation</a> covers the other forms.

## Related

<c-lbdocs.doc_card.grid cols="2">
  <c-lbdocs.doc_card title="labb.yaml" summary="Every css.packages and scan option" href="/docs/guide/references/config-yaml/" icon="rmx.settings-3" />
  <c-lbdocs.doc_card title="Developing packages" summary="Ship your own components and CSS to other projects" href="/docs/guide/going-further/developing-packages/" icon="rmx.box-3" />
</c-lbdocs.doc_card.grid>
