# CSS utility classes

## Add class names to inputs and content

Use the `classNames` parameter to add CSS utility classes to inputs and other content. In the example below, the available classes are used to create a composite address input.

{% hint style="info" %}
An `fmd-` prefix is added to all class names. However, this can be changed. [See the prefix section](#prefix) to learn more.
{% endhint %}

<figure><img src="https://824814026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FRq8uKg8VhNAvWTRL52uz%2Fuploads%2FbySk3ne5xompLiPjeDeN%2Fcss-utility-classes-3.png?alt=media&#x26;token=b96502b5-2e28-4abf-8e3e-851d5e959f48" alt=""><figcaption><p>Composite address input using CSS utility classes</p></figcaption></figure>

```javascript
import { Composer } from "formsmd";

const composer = new Composer({
  id: "my-form"
});

composer.h1("Enter your address", {
  classNames: ["form-question"]
})

composer.numberInput("house", {
  question: "House #",
  required: true,
  subfield: true,
  classNames: ["col-6"]
})

composer.numberInput("road", {
  question: "Road #",
  required: true,
  subfield: true,
  classNames: ["col-6"]
})

composer.textInput("city", {
  question: "City",
  required: true,
  subfield: true
})
```

Generates the following Markdown-like syntax:

```
#! id = my-form

# [.form-question] Enter your address

[.col-6]
house* = NumberInput(
  | question = House #
  | subfield
)

[.col-6]
road* = NumberInput(
  | question = Road #
  | subfield
)

city* = TextInput(
  | question = City
  | subfield
)
```

***

## Available CSS utility classes

The following CSS utility classes are available by default:

### Layout

All of the content uses a grid based, 12-column system. Add a `.col-{value}` class to any block-level element to have it occupy only a portion of the full width of the row. The layout class names come in the following formats:

* `.col-{value}` (only for tablets and desktops, `≥ 576px`)
* `.xs:col-{value}` (only for phones, `< 576px`)

The `{value}` can be any integer between `1` to `12` (included) or `auto`. For example, `.col-4` would span 4 columns.

```javascript
composer.numberInput("price", {
  question: "Price",
  labelStyle: "classic",
  classNames: ["col-4", "xs:col-6"],
  attrs: [
    {
      "name": "style",
      "value": "border: 1px solid;"
    }
  ]
})

composer.numberInput("quantity", {
  question: "Quantity",
  labelStyle: "classic",
  classNames: ["col-4", "xs:col-6"],
  attrs: [
    {
      "name": "style",
      "value": "border: 1px solid;"
    }
  ]
})
```

Generates the following Markdown-like syntax:

```
[.col-4 .xs:col-6 style="border: 1px solid;"]
price = NumberInput(
  | question = Price
  | labelStyle = classic
)

[.col-4 .xs:col-6 style="border: 1px solid;"]
quantity = NumberInput(
  | question = Quantity
  | labelStyle = classic
)
```

<figure><img src="https://824814026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FRq8uKg8VhNAvWTRL52uz%2Fuploads%2FdIosF5dzrm2uws9zTyh7%2Fcss-utility-classes-1.png?alt=media&#x26;token=93a3a0fc-5879-4d69-88eb-04535e7fc55c" alt=""><figcaption><p>CSS utility classes for layout</p></figcaption></figure>

Push and pull each column using the following classes:

* `.col-start-{value}`/`.xs:col-start-{value}` (sets `grid-column-start: {value}`)
* `.col-end-{value}`/`.xs:col-end-{value}` (sets `grid-column-end: {value}`)

Here, the `{value}` can be any integer between `1` to `13` (included) or `auto`.

```javascript
composer.numberInput("price", {
  question: "Price",
  labelStyle: "classic",
  classNames: ["col-4", "xs:col-6"],
  attrs: [
    {
      "name": "style",
      "value": "border: 1px solid;"
    }
  ]
})

composer.numberInput("quantity", {
  question: "Quantity",
  labelStyle: "classic",
  classNames: ["col-4", "col-start-9", "xs:col-6"],
  attrs: [
    {
      "name": "style",
      "value": "border: 1px solid;"
    }
  ]
})
```

Generates the following Markdown-like syntax:

```
[.col-4 .xs:col-6 style="border: 1px solid;"]
price = NumberInput(
  | question = Price
  | labelStyle = classic
)

[.col-4 .col-start-9 .xs:col-6 style="border: 1px solid;"]
quantity = NumberInput(
  | question = Quantity
  | labelStyle = classic
)
```

<figure><img src="https://824814026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FRq8uKg8VhNAvWTRL52uz%2Fuploads%2FvhaQw9TDHTkWyKTUQpkU%2Fcss-utility-classes-2.png?alt=media&#x26;token=9ca9eb0a-f072-4d93-8e8e-55760dc0b556" alt=""><figcaption><p>CSS utility classes for layout</p></figcaption></figure>

{% hint style="info" %}
The layout class names will also work in the exact same way for content inside `<div>` containers.
{% endhint %}

### Color

| Class            | Description                                                                      |
| ---------------- | -------------------------------------------------------------------------------- |
| `.text-emphasis` | `color: var(--fmd-emphasis-color)` (`black` in light mode, `white` in dark mode) |
| `.text-accent`   | Sets `color` to `accent`                                                         |

### Display and flex

| Class                      | Description                   |
| -------------------------- | ----------------------------- |
| `.d-inline`                | `display: inline`             |
| `.d-inline-block`          | `display: inline-block`       |
| `.d-block`                 | `display: block`              |
| `.d-inline-flex`           | `display: inline-flex`        |
| `.d-flex`                  | `display: flex`               |
| `.align-items-center`      | `align-items: center`         |
| `.justify-content-start`   | `justify-content: flex-start` |
| `.justify-content-center`  | `justify-content: center`     |
| `.justify-content-end`     | `justify-content: flex-end`   |
| `.justify-content-stretch` | `justify-content: stretch`    |
| `.d-none`                  | `display: none`               |

{% hint style="info" %}
The above classes also have phone-only (`< 576px`) variants available using the `.xs:` prefix. For example: `.xs:d-flex`, `.xs:align-items-center`, etc.
{% endhint %}

### Heading

| Class       | Description                        |
| ----------- | ---------------------------------- |
| `.h1`       | Matches the appearance of `<h1>`   |
| `.h2`       | Matches the appearance of `<h2>`   |
| `.h3`       | Matches the appearance of `<h3>`   |
| `.h4`       | Matches the appearance of `<h4>`   |
| `.h5`       | Matches the appearance of `<h5>`   |
| `.h6`       | Matches the appearance of `<h6>`   |
| `.anchored` | Adds an anchor link to the heading |

### Font size

| Class             | Description                                              |
| ----------------- | -------------------------------------------------------- |
| `.fs-lead`        | `font-size: var(--fmd-font-size-lg)` (`18px` by default) |
| `.specific-fs-12` | `font-size: 12px`                                        |
| `.specific-fs-14` | `font-size: 14px`                                        |
| `.specific-fs-16` | `font-size: 16px`                                        |
| `.specific-fs-18` | `font-size: 18px`                                        |
| `.specific-fs-20` | `font-size: 20px`                                        |

### Font weight

| Class          | Description            |
| -------------- | ---------------------- |
| `.fw-lighter`  | `font-weight: lighter` |
| `.fw-light`    | `font-weight: 300`     |
| `.fw-normal`   | `font-weight: 400`     |
| `.fw-medium`   | `font-weight: 500`     |
| `.fw-semibold` | `font-weight: 600`     |
| `.fw-bold`     | `font-weight: 700`     |
| `.fw-bolder`   | `font-weight: bolder`  |

### Form

| Class               | Description                                        |
| ------------------- | -------------------------------------------------- |
| `.form-question`    | Matches the appearance of a form field question    |
| `.form-description` | Matches the appearance of a form field description |

### Light/dark mode

| Class      | Description                        |
| ---------- | ---------------------------------- |
| `.hide-lm` | `display: none` only in light mode |
| `.hide-dm` | `display: none` only in dark mode  |

### List

| Class            | Description                                         |
| ---------------- | --------------------------------------------------- |
| `.list-inside`   | `padding-left: 0` and `list-style-position: inside` |
| `.list-unstyled` | `padding-left: 0` and `list-style: none`            |

### LTR/RTL

| Class       | Description                 |
| ----------- | --------------------------- |
| `.hide-ltr` | `display: none` only in LTR |
| `.hide-rtl` | `display: none` only in RTL |

### Spacing

The class names for the `margin` and `padding` utilities come in the following formats:

* `.m{sides}-{size}` for `margin`&#x20;
* `.p{sides}-{size}` for `padding`

#### {sides}

| {sides}     | Description                                              |
| ----------- | -------------------------------------------------------- |
| `t`         | Sets `margin-top` or `padding-top`                       |
| `b`         | Sets `margin-bottom` or `padding-bottom`                 |
| `s` (start) | Sets `margin-left` or `padding-left` (inverted in RTL)   |
| `e` (end)   | Sets `margin-right` or `padding-right` (inverted in RTL) |

#### {size}

| {size} | Description                                    |
| ------ | ---------------------------------------------- |
| `0`    | Sets `margin` or `padding` to `0`              |
| `1`    | Sets `margin` or `padding` to `4px`            |
| `2`    | Sets `margin` or `padding` to `8px`            |
| `3`    | Sets `margin` or `padding` to `16px`           |
| `auto` | Sets `margin-left` or `margin-right` to `auto` |

### Text alignment

| Class             | Description                                          |
| ----------------- | ---------------------------------------------------- |
| `.text-start`     | `text-align: left` (inverted in RTL)                 |
| `.text-center`    | `text-align: center`                                 |
| `.text-end`       | `text-align: right` (inverted in RTL)                |
| `.xs:text-start`  | `text-align: left` only on phones (inverted in RTL)  |
| `.xs:text-center` | `text-align: center` only on phones                  |
| `.xs:text-end`    | `text-align: right` only on phones (inverted in RTL) |

### Visibility

| Class        | Description          |
| ------------ | -------------------- |
| `.invisible` | `visibility: hidden` |

***

## Prefix

By default, an `fmd-` prefix is added to all class names when the `classNames` parameter is used. This is mainly used for scoping and avoiding collisions with other CSS that may be present. However, this can be changed using the `cssPrefix` [form setting](https://docs.forms.md/getting-started/settings). For example, setting `cssPrefix` to `"none"` would remove the prefix altogether. This means that you can use your own CSS utility classes, even the ones available in frameworks like Tailwind.

```javascript
const composer = new Composer({
  cssPrefix: "none",
  id: "my-form"
});

composer.emailInput("email", {
  question: "Join our mailing list",
  required: true,
  classNames: ["text-blue-500"]
});
```

Generates the following Markdown-like syntax:

```
#! css-prefix = none
#! id = my-form

[.text-blue-500]
email* = EmailInput(
  | question = Join our mailing list
)
```
