> ## Documentation Index
> Fetch the complete documentation index at: https://docs.expectedparrot.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Custom CSS

> CSS classes and HTML structure for styling human-facing surveys with custom CSS.

Custom CSS changes the appearance of a human survey, such as text size, spacing, colors, and logo dimensions. Use it to adapt the questionnaire to your study's visual design. For choices such as dropdowns, optional questions, or grouped pages, use the [Humanize schema](https://docs.expectedparrot.com/en/latest/humanize_schema.md).

The examples below use CSS selectors to identify parts of the survey: `.edsl-question-text`, for example, selects question wording. The HTML reference shows the structure EDSL generates; you do not need to write that HTML yourself.

## Applying custom CSS

### When creating a human survey

The following example gives the survey a light-gray background and makes question text bold and dark gray. Pass the CSS string under `survey.custom_css`; the other schema entries make the rating a dropdown and feedback optional.

```python theme={null}
from edsl import Survey, QuestionFreeText, QuestionMultipleChoice

survey = Survey([
    QuestionMultipleChoice(
        question_name="rating",
        question_text="Rate your experience.",
        question_options=["Good", "OK", "Bad"],
    ),
    QuestionFreeText(
        question_name="feedback",
        question_text="Any additional feedback you'd like to share?",
    ),
])

custom_css = """
.edsl-survey-container { background-color: #f9f9f9; }
.edsl-question-text { font-weight: bold; color: #333; }
"""

humanize_schema = {
    "questions": {
        "rating": {"format": {"type": "dropdown"}},
        "feedback": {"optional": True},
    },
    "survey": {"custom_css": custom_css},
}

survey.humanize(humanize_schema=humanize_schema)
```

Use `survey.preview(humanize_schema=humanize_schema)` to inspect the appearance before publishing, including how long questions and answer options fit on a phone. Pass `"survey": {"custom_css": None}` (or omit `custom_css`) to create the survey without custom styling.

### Updating CSS on an existing human survey

Use `Coop.patch_human_survey_css` to set or clear the CSS on a human survey that already exists.

```python theme={null}
from edsl import Coop

coop = Coop()

# Set or replace CSS
coop.patch_human_survey_css(
    human_survey_uuid="your-human-survey-uuid",
    css=".edsl-survey-container { background-color: #fff; }",
)

# Clear existing CSS
coop.patch_human_survey_css(
    human_survey_uuid="your-human-survey-uuid",
    css=None,
)
```

## Survey-level classes

| Class | Element | Notes |
| - | - | - |
| `edsl-survey-container` | Outermost container of the entire survey | Use to set background color for the whole survey. Carries `data-group-name` when the survey is presented by question group; see below |
| `edsl-survey-banner` | `<div>` holding the survey's logo, at the top of the survey | Only present when the survey has a logo. Give it a `background` for a banner; see below |
| `edsl-survey-banner-content` | Column inside `edsl-survey-banner` holding the logo | Lined up with `edsl-survey-content` |
| `edsl-logo` | The logo `<img>` inside `edsl-survey-banner` | 40px tall by default, width following the image. Resize with `height`; see below |
| `edsl-survey-content` | Column holding the page's questions and `edsl-survey-nav` | Questions are spaced by its `gap` |
| `edsl-survey-item` | `<div>` wrapping each question or instruction on the page | Carries `data-question-name` or `data-instruction-name`; see below |
| `edsl-instruction` | `<div>` holding an instruction's text | Inside `edsl-survey-item` |
| `edsl-survey-nav` | Row `<div>` holding the page's navigation buttons | Below the questions |
| `edsl-next-button` | `<button>` that submits the page | Disabled while the page submits; style that with `.edsl-next-button:disabled` |

## Targeting one question or page

Each question and instruction on a page is wrapped in `edsl-survey-item`, which carries
the item's name: `data-question-name` for a question, `data-instruction-name` for an
instruction. When the survey is presented by question group, `edsl-survey-container`
carries `data-group-name`, the group shown on the page.

```css theme={null}
/* One question */
.edsl-survey-item[data-question-name="age"] .edsl-question-text {
  font-weight: 700;
}

/* Every page of one group */
.edsl-survey-container[data-group-name="demographics"] {
  background: #f8fafc;
}
```

## Survey banner and logo

A survey with a logo shows it in `edsl-survey-banner` at the top of the survey, positioned
left, center or right as the author chose. Surveys without a logo have no banner, so rules
for these classes simply do nothing there.

Set the logo itself in the humanize schema under `survey.branding.logo`, referencing an
image you uploaded with `Coop().upload_human_survey_asset(...)`. See
[Humanize schema](https://docs.expectedparrot.com/en/latest/humanize_schema.md).

The logo is 40px tall by default, and its width follows the image's proportions. To resize
it, set its **height** and let the width follow:

```css theme={null}
/* A larger logo */
.edsl-logo {
  height: 80px;
}
```

To size it by width instead, set `width` together with `height: auto`. Setting both to
fixed values fits the logo inside that box without stretching it.

For a colored strip behind the logo, give the banner a background:

```css theme={null}
/* Logo on a colored banner */
.edsl-survey-banner {
  background: #2e7d32;
}
```

The banner spans the full width of the screen, and the logo inside it lines up with the
questions. To place the logo somewhere else, such as near the edge of the screen, style
`edsl-survey-banner-content`:

```css theme={null}
/* Logo near the edge of the screen */
.edsl-survey-banner-content {
  width: auto;
  padding: 0 24px;
}
```

## Progress indicator

The progress indicator sits above the question. Depending on how the survey is
configured, it shows as a bar or as a row of step markers. A survey can also hide it, in
which case nothing is rendered and there is nothing to style.

Both renderings put `edsl-progress` on their outer element. Use that class for rules that
should apply whichever one a survey uses.

### Bar

```html theme={null}
<div class="edsl-progress edsl-progress-bar">
  <div class="edsl-progress-track" role="progressbar" aria-valuenow="40">
    <div class="edsl-progress-fill"></div>
  </div>
  <!-- shown only when a label is configured -->
  <span class="edsl-progress-label">40%</span>
</div>
```

| Class | Element | Notes |
| - | - | - |
| `edsl-progress` | Outer element of either rendering | Present on both the bar and the steps |
| `edsl-progress-bar` | Outer `<div>` of the bar rendering | |
| `edsl-progress-track` | Unfilled groove | Set its `height`, `border-radius`, `background` |
| `edsl-progress-fill` | Filled portion | Color it, but leave its width alone. See below |
| `edsl-progress-label` | Percentage text under the bar | Absent when the label is turned off |

**Recolor the fill, don't resize it.** The fill is always as wide as the whole track, and
it slides sideways to reveal only the finished portion. Setting `width` on it will not
shorten it. Set `background`, `border-radius`, or `transition` instead.

### Steps

Each step is one `<li>` holding a marker, half of the connecting line on either side of
it, and an optional label below.

```html theme={null}
<ol class="edsl-progress edsl-progress-steps">
  <li class="edsl-progress-step" data-status="complete">
    <div>
      <!-- first step's incoming connector is hidden, not removed -->
      <span class="edsl-progress-connector edsl-progress-connector-incoming" data-status="upcoming"></span>
      <span class="edsl-progress-marker">1</span>
      <span class="edsl-progress-connector edsl-progress-connector-outgoing" data-status="complete"></span>
    </div>
    <!-- shown only for steps that have a label -->
    <span class="edsl-progress-label">Background</span>
  </li>

  <li class="edsl-progress-step" data-status="current">
    <div>
      <!-- filled, because the step before it is complete -->
      <span class="edsl-progress-connector edsl-progress-connector-incoming" data-status="complete"></span>
      <span class="edsl-progress-marker">2</span>
      <span class="edsl-progress-connector edsl-progress-connector-outgoing" data-status="upcoming"></span>
    </div>
    <span class="edsl-progress-label">Experience</span>
  </li>

  <li class="edsl-progress-step" data-status="upcoming">
    <div>
      <span class="edsl-progress-connector edsl-progress-connector-incoming" data-status="upcoming"></span>
      <span class="edsl-progress-marker">3</span>
      <!-- last step's outgoing connector is hidden, not removed -->
      <span class="edsl-progress-connector edsl-progress-connector-outgoing" data-status="upcoming"></span>
    </div>
    <span class="edsl-progress-label">Wrap-up</span>
  </li>
</ol>
```

| Class | Element | Notes |
| - | - | - |
| `edsl-progress-steps` | The `<ol>` holding the steps | |
| `edsl-progress-step` | One `<li>` per step | Equal-width column. Carries `data-status`: `complete`, `current` or `upcoming` |
| `edsl-progress-marker` | The circle for a step | Contains the step number, or is empty when markers are dots |
| `edsl-progress-connector` | Half of the line between two markers | Two per step, one on each side of the marker. Carries `data-status`: `complete` when filled, `upcoming` when not |
| `edsl-progress-connector-incoming` | The half arriving at the marker | On the left of the marker |
| `edsl-progress-connector-outgoing` | The half leaving the marker | On the right of the marker |
| `edsl-progress-label` | Text under a marker | Absent for steps without a label |

**Style markers and labels through their step.** Every `<li>` carries its step's
`data-status`, which is how you give the current marker a different look from the
finished ones.

**Style the line through its own status.** Each half carries its own `data-status`,
which does not match the status of the step it belongs to. The half arriving at the
current step is filled as soon as the step before it is done, so the current step
normally holds one filled half and one empty one. Select the filled line with
`.edsl-progress-connector[data-status="complete"]`. Reaching for
`.edsl-progress-step[data-status="complete"] .edsl-progress-connector` instead leaves
that first half gray, and the line stops short of where the respondent actually is.

```css theme={null}
.edsl-progress-step[data-status="current"] .edsl-progress-marker { border-color: #b91c1c; color: #b91c1c; }
.edsl-progress-step[data-status="complete"] .edsl-progress-marker { background: #b91c1c; border-color: #b91c1c; }
.edsl-progress-connector[data-status="complete"] { background: #b91c1c; }
```

**To reach a single segment, combine a step's status with a connector's.** Include the
connector's position class as well, since a step's two halves are otherwise identical. The rule below
picks out the filled half arriving at the step the respondent is on, and gives it a
gradient so the line brightens as it reaches them:

```css theme={null}
.edsl-progress-step[data-status="current"]
  .edsl-progress-connector-incoming[data-status="complete"] {
  background: linear-gradient(to right, #b91c1c, #f87171);
}
```

Finally, markers come in two shapes: numbered circles and small dots. The survey's
configuration picks the shape, not your CSS. A rule that assumes a size, such as a fixed
`width`, will look wrong under the other shape, so check the survey renders with the
shape you expect.

## Common question classes

These classes are present on every question regardless of type.

| Class | Element | Notes |
| - | - | - |
| `edsl-question` | Outermost `<div>` of every question | Always present |
| `edsl-question-text` | Question prompt `<div>` | Rendered from `question_text` |
| `edsl-question-image` | `<img>` embedded in a question | Image blocks in question text |
| `edsl-error` | Error message `<p>` | Shown only when the answer is invalid |

### Options

Questions answered by picking from a list share these classes.

| Class | Element | Notes |
| - | - | - |
| `edsl-options` | Container wrapping all of a question's options | |
| `edsl-option` | `<label>` for one option | Wraps the control and its text, so a click anywhere in the row answers |
| `edsl-option-label` | `<span>` next to the radio or checkbox | |
| `edsl-option-content` | `<span>` wrapping an option's rendered label | Also used for budget labels, rank items, and matrix rows and columns |
| `edsl-option-text` | Text `<span>` inside `edsl-option-content` | |
| `edsl-option-image` | `<img>` inside `edsl-option-content` | When an option references an image |
| `edsl-option-media-unavailable` | `<span>` shown in place of an option's file | When the file isn't an image or can't be found |
| `edsl-select` | `<select>` | When the humanize format is `dropdown`. Its options are plain text |

```html theme={null}
<label class="edsl-option">
  <!-- the radio or checkbox; see below -->
  <span class="edsl-radio-control" data-unchecked>…</span>
  <span class="edsl-option-label">
    <span class="edsl-option-content">
      <span class="edsl-option-text">Golden retriever</span>
      <!-- only when the option references an image -->
      <img class="edsl-option-image" src="…" alt="dog.jpg" />
    </span>
  </span>
</label>
```

### Radios and checkboxes

Each radio and checkbox is drawn by a `<span>`, with the `<input>` inside it hidden from
view. Style the span, not the input.

```html theme={null}
<span class="edsl-radio-control" data-checked>
  <input class="edsl-radio" type="radio" checked />
  <span class="edsl-radio-indicator" data-checked></span>
</span>

<span class="edsl-checkbox-control" data-unchecked>
  <input class="edsl-checkbox" type="checkbox" />
  <span class="edsl-checkbox-indicator" data-unchecked><svg>…</svg></span>
</span>
```

| Class | Element | Notes |
| - | - | - |
| `edsl-radio-control` | `<span>` drawn in the radio's place: the circle | Carries `data-checked` while selected and `data-unchecked` while not |
| `edsl-radio` | The `<input type="radio">` | Hidden, so styling it has no visible effect |
| `edsl-radio-indicator` | `<span>` for the dot | Carries `data-checked` or `data-unchecked`. Hidden while unselected |
| `edsl-checkbox-control` | `<span>` drawn in the checkbox's place: the box | Carries `data-checked` while selected and `data-unchecked` while not |
| `edsl-checkbox` | The `<input type="checkbox">` | Hidden, so styling it has no visible effect |
| `edsl-checkbox-indicator` | `<span>` around the tick `<svg>` | Carries `data-checked` or `data-unchecked`. The tick is drawn in `currentColor` |

```css theme={null}
/* Green controls */
.edsl-radio-control[data-checked],
.edsl-checkbox-control[data-checked] {
  border-color: #2e7d32;
}
.edsl-checkbox-control[data-checked] {
  background: #2e7d32;
}
.edsl-radio-indicator {
  background: #2e7d32;
}
```

To style the row of a selected option, use `.edsl-option:has(.edsl-radio:checked)`.

## Question-specific HTML

### Budget

```html theme={null}
<div class="edsl-question edsl-budget-question">
  <div class="edsl-question-text">Allocate $100 across categories.</div>
  <div class="edsl-budget-options">
    <div class="edsl-budget-item">
      <div>
        <label class="edsl-budget-label">
          <span class="edsl-option-content">
            <span class="edsl-option-text">Food</span>
          </span>
        </label>
        <input class="edsl-budget-input" type="text" />
      </div>
    </div>
    <div class="edsl-budget-item">
      <div>
        <label class="edsl-budget-label">
          <span class="edsl-option-content">
            <span class="edsl-option-text">Transport</span>
          </span>
        </label>
        <input class="edsl-budget-input" type="text" />
      </div>
    </div>
    <div class="edsl-budget-total">
      <span>Total</span>
      <span>75</span>
    </div>
  </div>
  <p class="edsl-error">…</p>
</div>
```

### Checkbox

```html theme={null}
<div class="edsl-question edsl-checkbox-question">
  <div class="edsl-question-text">Select all that apply.</div>

  <div class="edsl-options">
    <label class="edsl-option">
      <span class="edsl-checkbox-control" data-checked>
        <input class="edsl-checkbox" type="checkbox" checked />
        <span class="edsl-checkbox-indicator" data-checked><svg>…</svg></span>
      </span>
      <span class="edsl-option-label">
        <span class="edsl-option-content">
          <span class="edsl-option-text">Option A</span>
        </span>
      </span>
    </label>
    <label class="edsl-option">
      <span class="edsl-checkbox-control" data-unchecked>
        <input class="edsl-checkbox" type="checkbox" />
        <span class="edsl-checkbox-indicator" data-unchecked><svg>…</svg></span>
      </span>
      <span class="edsl-option-label">
        <span class="edsl-option-content">
          <span class="edsl-option-text">Option B</span>
        </span>
      </span>
    </label>
  </div>

  <!-- shown unless the humanize schema turns it off -->
  <label class="edsl-select-all">
    <span class="edsl-checkbox-control" data-unchecked>
      <input class="edsl-checkbox" type="checkbox" />
      <span class="edsl-checkbox-indicator" data-unchecked><svg>…</svg></span>
    </span>
    <span class="edsl-option-label">Select all</span>
  </label>

  <p class="edsl-error">…</p>
</div>
```

### Checkbox with other

```html theme={null}
<div class="edsl-question edsl-checkbox-with-other-question">
  <div class="edsl-question-text">Which tools do you use?</div>
  <div class="edsl-options">
    <label class="edsl-option">
      <span class="edsl-checkbox-control" data-unchecked>
        <input class="edsl-checkbox" type="checkbox" />
        <span class="edsl-checkbox-indicator" data-unchecked><svg>…</svg></span>
      </span>
      <span class="edsl-option-label">
        <span class="edsl-option-content">
          <span class="edsl-option-text">Spreadsheets</span>
        </span>
      </span>
    </label>
    <!-- … -->

    <div class="edsl-other-option">
      <label class="edsl-option">
        <span class="edsl-checkbox-control" data-checked>
          <input class="edsl-checkbox" type="checkbox" checked />
          <span class="edsl-checkbox-indicator" data-checked><svg>…</svg></span>
        </span>
        <span class="edsl-option-label">Other</span>
      </label>
      <div>
        <p class="edsl-other-hint">Please enter one item per box.</p>
        <ul>
          <!-- one per item entered -->
          <li>
            <input class="edsl-other-input" type="text" placeholder="Enter an item" />
            <!-- hidden while there is only one box -->
            <button class="edsl-other-remove" type="button"><svg>…</svg></button>
          </li>
        </ul>
        <!-- shown once an item has been entered -->
        <div>
          <button class="edsl-other-add" type="button"><svg>…</svg> Add another</button>
        </div>
      </div>
    </div>
  </div>
  <p class="edsl-error">…</p>
</div>
```

### EDSL object

```html theme={null}
<div class="edsl-question edsl-object-question">
  <div class="edsl-question-text">Select the agent list to use.</div>
  <div>
    <button class="edsl-object-select-btn" type="button">Select an Agent List</button>
  </div>

  <!-- shown after an object is selected -->
  <div class="edsl-object-selected">
    <span>Selected Agent List</span>
    <p>My agents - Q1 2025</p>
    <span>UUID: a1b2c3d4-…</span>
    <div>
      <button type="button">View</button>
      <button type="button">Clear</button>
    </div>
  </div>

  <p class="edsl-error">…</p>
</div>
```

### File upload

```html theme={null}
<div class="edsl-question edsl-file-upload-question">
  <div class="edsl-question-text">Upload supporting documents.</div>

  <!-- carries data-dragging while a drag is in progress -->
  <div class="edsl-file-upload-dropzone" data-dragging>

    <!-- clickable / drag-and-drop target -->
    <div role="button" class="edsl-file-upload-target">
      <input type="file" multiple class="sr-only" />
      <div class="edsl-file-upload-icon-wrapper">
        <!-- upload icon -->
        <svg class="edsl-file-upload-icon">…</svg>
      </div>
      <p class="edsl-file-upload-title">Upload files</p>
      <p class="edsl-file-upload-subtitle">Drag & drop or click to browse</p>
      <!-- shown when file-type / size constraints are set -->
      <p class="edsl-file-upload-hints">All file types · Max 10 files · Up to 1 GB per file</p>
    </div>

    <!-- shown only when there are file-level errors -->
    <div class="edsl-file-upload-errors">
      <!-- error messages -->
      <button type="button"><!-- dismiss --></button>
    </div>

    <!-- shown only when files have been added -->
    <div class="edsl-file-list">
      <div class="edsl-file-list-header">
        <span>Files (2)</span>
        <button type="button" class="edsl-file-remove-all">Remove all</button>
      </div>

      <!-- card layout (small screens) -->
      <div class="edsl-file-cards">
        <!-- data-status: uploading, done or error -->
        <div class="edsl-file-item" data-status="uploading">
          <div class="edsl-file-item-icon-wrapper">
            <svg class="edsl-file-item-icon">…</svg>
          </div>
          <div>
            <p class="edsl-file-item-name">doc1.pdf</p>
            <div>
              <p class="edsl-file-item-size">24 KB</p>
              <span class="edsl-file-item-status">
                <!-- while uploading: -->
                <span class="edsl-file-status-uploading">
                  <div class="edsl-file-progress-track">
                    <div class="edsl-file-progress-fill" style="width: 60%"></div>
                  </div>
                  Uploading…
                </span>
                <!-- on success: -->
                <span class="edsl-file-status-done">Done</span>
                <!-- on failure: -->
                <span class="edsl-file-status-error">Failed</span>
              </span>
            </div>
          </div>
          <button type="button" class="edsl-file-item-remove"><!-- trash icon --></button>
        </div>
      </div>

      <!-- table layout (medium+ screens) -->
      <div class="edsl-file-table-wrapper">
        <table class="edsl-file-table">
          <thead class="edsl-file-table-header">
            <tr class="edsl-file-table-header-row">
              <th class="edsl-file-table-header-cell">Name</th>
              <th class="edsl-file-table-header-cell">Size</th>
              <th class="edsl-file-table-header-cell">Upload Status</th>
              <th class="edsl-file-table-header-cell">Actions</th>
            </tr>
          </thead>
          <tbody>
            <!-- data-status: uploading, done or error -->
            <tr class="edsl-file-table-row" data-status="uploading">
              <td>
                <svg class="edsl-file-item-icon">…</svg>
                <span>doc1.pdf</span>
              </td>
              <td>24 KB</td>
              <td>
                <!-- one of: -->
                <span class="edsl-file-status-uploading">
                  <div class="edsl-file-progress-track">
                    <div class="edsl-file-progress-fill" style="width: 60%"></div>
                  </div>
                </span>
                <span class="edsl-file-status-done">Done</span>
                <span class="edsl-file-status-error">Failed</span>
              </td>
              <td>
                <button type="button" class="edsl-file-item-remove"><!-- trash icon --></button>
              </td>
            </tr>
          </tbody>
        </table>
      </div>
    </div>

  </div>
  <p class="edsl-error">…</p>
</div>
```

### Free text

```html theme={null}
<div class="edsl-question edsl-free-text-question">
  <div class="edsl-question-text">Tell us about yourself.</div>
  <textarea class="edsl-textarea" rows="4"></textarea>
  <p class="edsl-error">…</p>
</div>
```

### Linear scale

> [tab] Radio
>
> When humanize format is `radio` (default):
>
> ```html theme={null}
> <div class="edsl-question edsl-linear-scale-question">
>   <div class="edsl-question-text">Rate from 1 to 5.</div>
>   <div class="edsl-options">
>     <label class="edsl-option">
>       <span class="edsl-radio-control" data-unchecked>
>         <input class="edsl-radio" type="radio" value="1" />
>         <span class="edsl-radio-indicator" data-unchecked></span>
>       </span>
>       <span class="edsl-option-label">
>         <span class="edsl-option-content">
>           <span class="edsl-option-text">1 - Very poor</span>
>         </span>
>       </span>
>     </label>
>     <label class="edsl-option">
>       <span class="edsl-radio-control" data-unchecked>
>         <input class="edsl-radio" type="radio" value="2" />
>         <span class="edsl-radio-indicator" data-unchecked></span>
>       </span>
>       <span class="edsl-option-label">
>         <span class="edsl-option-content">
>           <span class="edsl-option-text">2</span>
>         </span>
>       </span>
>     </label>
>     <!-- … -->
>     <label class="edsl-option">
>       <span class="edsl-radio-control" data-unchecked>
>         <input class="edsl-radio" type="radio" value="5" />
>         <span class="edsl-radio-indicator" data-unchecked></span>
>       </span>
>       <span class="edsl-option-label">
>         <span class="edsl-option-content">
>           <span class="edsl-option-text">5 - Excellent</span>
>         </span>
>       </span>
>     </label>
>   </div>
>   <p class="edsl-error">…</p>
> </div>
> ```

> [tab] Dropdown
>
> When humanize format is `dropdown`:
>
> ```html theme={null}
> <div class="edsl-question edsl-linear-scale-question">
>   <div class="edsl-question-text">Rate from 1 to 5.</div>
>   <div class="edsl-options">
>     <select class="edsl-select" name="q1">
>       <option value="">Select...</option>
>       <option value="1">1 - Very poor</option>
>       <option value="2">2</option>
>       <option value="3">3</option>
>       <option value="4">4</option>
>       <option value="5">5 - Excellent</option>
>     </select>
>   </div>
>   <p class="edsl-error">…</p>
> </div>
> ```

### Likert five

> [tab] Radio
>
> When humanize format is `radio` (default):
>
> ```html theme={null}
> <div class="edsl-question edsl-likert-question">
>   <div class="edsl-question-text">How satisfied are you?</div>
>   <div class="edsl-options">
>     <label class="edsl-option">
>       <span class="edsl-radio-control" data-unchecked>
>         <input class="edsl-radio" type="radio" value="Strongly disagree" />
>         <span class="edsl-radio-indicator" data-unchecked></span>
>       </span>
>       <span class="edsl-option-label">
>         <span class="edsl-option-content">
>           <span class="edsl-option-text">Strongly disagree</span>
>         </span>
>       </span>
>     </label>
>     <!-- … -->
>     <label class="edsl-option">
>       <span class="edsl-radio-control" data-unchecked>
>         <input class="edsl-radio" type="radio" value="Strongly agree" />
>         <span class="edsl-radio-indicator" data-unchecked></span>
>       </span>
>       <span class="edsl-option-label">
>         <span class="edsl-option-content">
>           <span class="edsl-option-text">Strongly agree</span>
>         </span>
>       </span>
>     </label>
>   </div>
>   <p class="edsl-error">…</p>
> </div>
> ```

> [tab] Dropdown
>
> When humanize format is `dropdown`:
>
> ```html theme={null}
> <div class="edsl-question edsl-likert-question">
>   <div class="edsl-question-text">How satisfied are you?</div>
>   <div class="edsl-options">
>     <select class="edsl-select" name="q1">
>       <option value="">Select...</option>
>       <option value="Strongly disagree">Strongly disagree</option>
>       <option value="Disagree">Disagree</option>
>       <option value="Neutral">Neutral</option>
>       <option value="Agree">Agree</option>
>       <option value="Strongly agree">Strongly agree</option>
>     </select>
>   </div>
>   <p class="edsl-error">…</p>
> </div>
> ```

### List

```html theme={null}
<div class="edsl-question edsl-list-question">
  <div class="edsl-question-text">List your top hobbies.</div>
  <p>Please enter one item per line.</p>
  <textarea class="edsl-textarea" rows="4"></textarea>
  <p class="edsl-error">…</p>
</div>
```

### Matrix

> [tab] Table
>
> When humanize format is `table` (default):
>
> ```html theme={null}
> <div class="edsl-question edsl-matrix-question">
>   <div class="edsl-question-text">Rate each item.</div>
>   <div class="edsl-matrix-views">
>
>     <!-- shown below 768px -->
>     <div class="edsl-matrix-stack-view">
>       <div class="edsl-matrix-stack">
>         <div class="edsl-matrix-stack-row">
>           <div class="edsl-matrix-stack-item">
>             <span class="edsl-option-content">
>               <span class="edsl-option-text">Price</span>
>             </span>
>           </div>
>           <div class="edsl-options" role="radiogroup">
>             <label class="edsl-option">
>               <span class="edsl-radio-control" data-unchecked>
>                 <input class="edsl-radio" type="radio" value="1" />
>                 <span class="edsl-radio-indicator" data-unchecked></span>
>               </span>
>               <span class="edsl-option-label">
>                 <span class="edsl-option-content">
>                   <span class="edsl-option-text">1 - Poor</span>
>                 </span>
>               </span>
>             </label>
>             <!-- … -->
>           </div>
>         </div>
>         <div class="edsl-matrix-stack-row"><!-- … --></div>
>       </div>
>     </div>
>
>     <!-- shown from 768px up -->
>     <div class="edsl-matrix-table-view">
>       <div>
>         <table class="edsl-matrix-table">
>           <colgroup>
>             <col class="edsl-matrix-item-column" />
>             <!-- one per option -->
>             <col class="edsl-matrix-option-column" />
>             <col class="edsl-matrix-option-column" />
>             <col class="edsl-matrix-option-column" />
>           </colgroup>
>           <thead>
>             <tr class="edsl-matrix-header-row">
>               <th><!-- row label column --></th>
>               <th>
>                 <div>
>                   <!-- shown only when the option has a label -->
>                   <span>Poor</span>
>                   <span>
>                     <span class="edsl-option-content">
>                       <span class="edsl-option-text">1</span>
>                     </span>
>                   </span>
>                 </div>
>               </th>
>               <!-- … -->
>             </tr>
>           </thead>
>           <tbody>
>             <tr class="edsl-matrix-row">
>               <td class="edsl-matrix-label-cell">
>                 <span class="edsl-option-content">
>                   <span class="edsl-option-text">Price</span>
>                 </span>
>               </td>
>               <td class="edsl-matrix-cell">
>                 <label>
>                   <span>
>                     <span class="edsl-radio-control" data-unchecked>
>                       <input class="edsl-radio" type="radio" value="1" />
>                       <span class="edsl-radio-indicator" data-unchecked></span>
>                     </span>
>                   </span>
>                 </label>
>               </td>
>               <!-- … -->
>             </tr>
>             <tr class="edsl-matrix-row"><!-- … --></tr>
>           </tbody>
>         </table>
>       </div>
>     </div>
>
>   </div>
>   <p class="edsl-error">…</p>
> </div>
> ```
>
> Both views are always in the page, and CSS picks which one shows. To keep the table at
> every width:
>
> ```css theme={null}
> .edsl-matrix-stack-view { display: none; }
> .edsl-matrix-table-view { display: block; }
> ```
>
> Row labels take 25% of the table's width by default, and the option columns share the
> rest. To change that, set `--edsl-matrix-item-column` to a percentage, on
> `.edsl-matrix-table` or on `.edsl-survey-container`:
>
> ```css theme={null}
> .edsl-matrix-table { --edsl-matrix-item-column: 40%; }
> ```

> [tab] Carousel
>
> When humanize format is `carousel`, rows are shown one at a time:
>
> ```html theme={null}
> <div class="edsl-question edsl-matrix-question">
>   <div class="edsl-question-text">Rate each item.</div>
>   <div class="edsl-matrix-carousel">
>     <div>
>       <div>
>         <!-- one slide per row -->
>         <div class="edsl-matrix-carousel-slide">
>           <div class="edsl-matrix-carousel-item">
>             <span class="edsl-option-content">
>               <span class="edsl-option-text">Price</span>
>             </span>
>           </div>
>         </div>
>         <div class="edsl-matrix-carousel-slide"><!-- … --></div>
>       </div>
>     </div>
>
>     <div class="edsl-matrix-carousel-nav">
>       <button class="edsl-matrix-carousel-button" type="button" aria-label="Previous item"><svg>…</svg></button>
>       <span class="edsl-matrix-carousel-status">1 of 8</span>
>       <button class="edsl-matrix-carousel-button" type="button" aria-label="Next item"><svg>…</svg></button>
>     </div>
>
>     <!-- the options for the row on screen -->
>     <div class="edsl-options" role="radiogroup">
>       <label class="edsl-option">
>         <span class="edsl-radio-control" data-unchecked>
>           <input class="edsl-radio" type="radio" value="1" />
>           <span class="edsl-radio-indicator" data-unchecked></span>
>         </span>
>         <span class="edsl-option-label">
>           <span class="edsl-option-content">
>             <span class="edsl-option-text">1 - Poor</span>
>           </span>
>         </span>
>       </label>
>       <!-- … -->
>     </div>
>   </div>
>   <p class="edsl-error">…</p>
> </div>
> ```

### Multiple choice

> [tab] Radio
>
> When humanize format is `radio` (default):
>
> ```html theme={null}
> <div class="edsl-question edsl-multiple-choice-question">
>   <div class="edsl-question-text">Which fruit do you prefer?</div>
>   <div class="edsl-options">
>     <label class="edsl-option">
>       <span class="edsl-radio-control" data-unchecked>
>         <input class="edsl-radio" type="radio" value="Apple" />
>         <span class="edsl-radio-indicator" data-unchecked></span>
>       </span>
>       <span class="edsl-option-label">
>         <span class="edsl-option-content">
>           <span class="edsl-option-text">Apple</span>
>         </span>
>       </span>
>     </label>
>     <label class="edsl-option">
>       <span class="edsl-radio-control" data-unchecked>
>         <input class="edsl-radio" type="radio" value="Banana" />
>         <span class="edsl-radio-indicator" data-unchecked></span>
>       </span>
>       <span class="edsl-option-label">
>         <span class="edsl-option-content">
>           <span class="edsl-option-text">Banana</span>
>         </span>
>       </span>
>     </label>
>     <label class="edsl-option">
>       <span class="edsl-radio-control" data-unchecked>
>         <input class="edsl-radio" type="radio" value="Cherry" />
>         <span class="edsl-radio-indicator" data-unchecked></span>
>       </span>
>       <span class="edsl-option-label">
>         <span class="edsl-option-content">
>           <span class="edsl-option-text">Cherry</span>
>         </span>
>       </span>
>     </label>
>   </div>
>   <!-- shown only on error -->
>   <p class="edsl-error"><svg>…</svg> Please select an option.</p>
> </div>
> ```

> [tab] Dropdown
>
> When humanize format is `dropdown`:
>
> ```html theme={null}
> <div class="edsl-question edsl-multiple-choice-question">
>   <div class="edsl-question-text">Which fruit do you prefer?</div>
>   <div class="edsl-options">
>     <select class="edsl-select" name="q1">
>       <option value="">Select...</option>
>       <option value="Apple">Apple</option>
>       <option value="Banana">Banana</option>
>       <option value="Cherry">Cherry</option>
>     </select>
>   </div>
>   <p class="edsl-error">…</p>
> </div>
> ```

### Multiple choice with other

```html theme={null}
<div class="edsl-question edsl-multiple-choice-with-other-question">
  <div class="edsl-question-text">How did you hear about us?</div>
  <div class="edsl-options">
    <label class="edsl-option">
      <span class="edsl-radio-control" data-unchecked>
        <input class="edsl-radio" type="radio" value="Search engine" />
        <span class="edsl-radio-indicator" data-unchecked></span>
      </span>
      <span class="edsl-option-label">
        <span class="edsl-option-content">
          <span class="edsl-option-text">Search engine</span>
        </span>
      </span>
    </label>
    <label class="edsl-option">
      <span class="edsl-radio-control" data-unchecked>
        <input class="edsl-radio" type="radio" value="Friend" />
        <span class="edsl-radio-indicator" data-unchecked></span>
      </span>
      <span class="edsl-option-label">
        <span class="edsl-option-content">
          <span class="edsl-option-text">Friend</span>
        </span>
      </span>
    </label>

    <div class="edsl-other-option">
      <label class="edsl-option">
        <span class="edsl-radio-control" data-unchecked>
          <input class="edsl-radio" type="radio" value="Other" />
          <span class="edsl-radio-indicator" data-unchecked></span>
        </span>
        <span class="edsl-option-label">Other</span>
      </label>
      <div>
        <input class="edsl-other-input" type="text" />
      </div>
    </div>
  </div>
  <p class="edsl-error">…</p>
</div>
```

### Numerical

> [tab] Input
>
> When humanize format is `input` (default):
>
> ```html theme={null}
> <div class="edsl-question edsl-numerical-question">
>   <div class="edsl-question-text">Enter your age.</div>
>   <input class="edsl-input" type="number" />
>   <p class="edsl-error">…</p>
> </div>
> ```

> [tab] Slider
>
> When humanize format is `slider`:
>
> ```html theme={null}
> <div class="edsl-question edsl-numerical-question">
>   <div class="edsl-question-text">On a scale of 0 to 100, how likely are you to recommend?</div>
>   <div>
>     <input class="edsl-input edsl-numerical-slider" type="range" min="0" max="100" step="1" value="50" />
>     <div>
>       <span>0</span>
>       <span>50</span>
>       <span>100</span>
>     </div>
>   </div>
>   <p class="edsl-error">…</p>
> </div>
> ```

### Rank

```html theme={null}
<div class="edsl-question edsl-rank-question">
  <div class="edsl-question-text">Rank these items from most to least preferred.</div>
  <div class="edsl-rank-list">
    <div class="edsl-rank-options">

      <div class="edsl-rank-item">
        <select class="edsl-rank-select">
          <option value="1">1</option>
          <option value="2">2</option>
          <option value="3">3</option>
          <!-- only when the question limits how many items are ranked -->
          <option value="not-ranked">Not ranked</option>
        </select>
        <span class="edsl-rank-item-label">
          <span class="edsl-option-content">
            <span class="edsl-option-text">Item A</span>
          </span>
        </span>
        <div class="edsl-rank-drag-handle">
          <!-- GripVertical icon (drag handle) -->
        </div>
      </div>

      <div class="edsl-rank-item">
        <select class="edsl-rank-select">…</select>
        <span class="edsl-rank-item-label">Item B</span>
        <div class="edsl-rank-drag-handle">…</div>
      </div>

      <div class="edsl-rank-item">
        <select class="edsl-rank-select">…</select>
        <span class="edsl-rank-item-label">Item C</span>
        <div class="edsl-rank-drag-handle">…</div>
      </div>

    </div>
  </div>
  <p class="edsl-error">…</p>
</div>
```

### Survey message

```html theme={null}
<div class="edsl-question edsl-survey-message-question">
  <div class="edsl-question-text">Thanks! The next few questions are about your work.</div>
</div>
```

### Top K

```html theme={null}
<div class="edsl-question edsl-top-k-question">
  <div class="edsl-question-text">Pick your top 2.</div>
  <div class="edsl-options">
    <label class="edsl-option">
      <span class="edsl-checkbox-control" data-unchecked>
        <input class="edsl-checkbox" type="checkbox" />
        <span class="edsl-checkbox-indicator" data-unchecked><svg>…</svg></span>
      </span>
      <span class="edsl-option-label">
        <span class="edsl-option-content">
          <span class="edsl-option-text">Choice A</span>
        </span>
      </span>
    </label>
    <label class="edsl-option">
      <span class="edsl-checkbox-control" data-unchecked>
        <input class="edsl-checkbox" type="checkbox" />
        <span class="edsl-checkbox-indicator" data-unchecked><svg>…</svg></span>
      </span>
      <span class="edsl-option-label">
        <span class="edsl-option-content">
          <span class="edsl-option-text">Choice B</span>
        </span>
      </span>
    </label>
    <label class="edsl-option">
      <span class="edsl-checkbox-control" data-unchecked>
        <input class="edsl-checkbox" type="checkbox" />
        <span class="edsl-checkbox-indicator" data-unchecked><svg>…</svg></span>
      </span>
      <span class="edsl-option-label">
        <span class="edsl-option-content">
          <span class="edsl-option-text">Choice C</span>
        </span>
      </span>
    </label>
  </div>
  <p class="edsl-error">…</p>
</div>
```

### Yes/no

> [tab] Radio
>
> When humanize format is `radio` (default):
>
> ```html theme={null}
> <div class="edsl-question edsl-yes-no-question">
>   <div class="edsl-question-text">Do you agree?</div>
>   <div class="edsl-options">
>     <label class="edsl-option">
>       <span class="edsl-radio-control" data-unchecked>
>         <input class="edsl-radio" type="radio" value="Yes" />
>         <span class="edsl-radio-indicator" data-unchecked></span>
>       </span>
>       <span class="edsl-option-label">
>         <span class="edsl-option-content">
>           <span class="edsl-option-text">Yes</span>
>         </span>
>       </span>
>     </label>
>     <label class="edsl-option">
>       <span class="edsl-radio-control" data-unchecked>
>         <input class="edsl-radio" type="radio" value="No" />
>         <span class="edsl-radio-indicator" data-unchecked></span>
>       </span>
>       <span class="edsl-option-label">
>         <span class="edsl-option-content">
>           <span class="edsl-option-text">No</span>
>         </span>
>       </span>
>     </label>
>   </div>
>   <p class="edsl-error">…</p>
> </div>
> ```

> [tab] Dropdown
>
> When humanize format is `dropdown`:
>
> ```html theme={null}
> <div class="edsl-question edsl-yes-no-question">
>   <div class="edsl-question-text">Do you agree?</div>
>   <div class="edsl-options">
>     <select class="edsl-select" name="q1">
>       <option value="">Select...</option>
>       <option value="Yes">Yes</option>
>       <option value="No">No</option>
>     </select>
>   </div>
>   <p class="edsl-error">…</p>
> </div>
> ```

## Comment field

If a question has `comment` configured in the humanize schema, an additional comment input is rendered under that question.

```html theme={null}
<div class="edsl-comment-field">
  <label class="edsl-question-text">Why did you choose this answer?</label>
  <textarea class="edsl-textarea" rows="2"></textarea>
</div>
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.