Skip to main content

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.

Every question component supported by humanize has edsl-* CSS classes so you can customise the survey appearance.

Applying custom CSS

When creating a human survey

Pass your CSS string in the humanize_schema under survey.custom_css.
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)
Pass "survey": {"custom_css": None} (or omit custom_css) to create the survey without any custom CSS.

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.
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

ClassElementNotes
edsl-survey-containerOutermost container of the entire surveyUse to set background color for the whole survey

Common question classes

These classes are present on every question regardless of type.
ClassElementNotes
edsl-questionOutermost <div> of every questionAlways present
edsl-question-textQuestion prompt <div>Rendered from question_text
edsl-question-image<img> embedded in a questionImage blocks in question text

Question-specific HTML

Budget

<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">
      <label class="edsl-budget-label">Food</label>
      <input class="edsl-budget-input" type="text" />
    </div>
    <div class="edsl-budget-item">
      <label class="edsl-budget-label">Transport</label>
      <input class="edsl-budget-input" type="text" />
    </div>
    <div class="edsl-budget-total">
      <span>Total</span>
      <span>75</span>
    </div>
  </div>
  <p class="edsl-error"></p>
</div>

Checkbox

<div class="edsl-question edsl-checkbox-question">
  <div class="edsl-question-text">Select all that apply.</div>

  <div class="edsl-select-all">
    <input class="edsl-checkbox" type="checkbox" />
    <label class="edsl-option-label">Select All</label>
  </div>

  <div class="edsl-options">
    <div class="edsl-option">
      <input class="edsl-checkbox" type="checkbox" />
      <label class="edsl-option-label">Option A</label>
    </div>
    <div class="edsl-option">
      <input class="edsl-checkbox" type="checkbox" />
      <label class="edsl-option-label">Option B</label>
    </div>
  </div>
  <p class="edsl-error"></p>
</div>

EDSL object

<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

<div class="edsl-question edsl-file-upload-question">
  <div class="edsl-question-text">Upload supporting documents.</div>

  <!-- edsl-file-upload-dragging is added to this element while a drag is in progress -->
  <div class="edsl-file-upload-dropzone [edsl-file-upload-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">
        <div class="edsl-file-item">
          <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>
            <tr class="edsl-file-table-row">
              <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

<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

When humanize format is radio (default):
<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">
      <input class="edsl-radio" type="radio" value="1" />
      <span class="edsl-option-label">1 - Very poor</span>
    </label>
    <label class="edsl-option">
      <input class="edsl-radio" type="radio" value="2" />
      <span class="edsl-option-label">2</span>
    </label>
    <!-- … -->
    <label class="edsl-option">
      <input class="edsl-radio" type="radio" value="5" />
      <span class="edsl-option-label">5 - Excellent</span>
    </label>
  </div>
  <p class="edsl-error"></p>
</div>

Likert five

When humanize format is radio (default):
<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">
      <input class="edsl-radio" type="radio" value="Strongly disagree" />
      <span class="edsl-option-label">Strongly disagree</span>
    </label>
    <label class="edsl-option">
      <input class="edsl-radio" type="radio" value="Disagree" />
      <span class="edsl-option-label">Disagree</span>
    </label>
    <label class="edsl-option">
      <input class="edsl-radio" type="radio" value="Neutral" />
      <span class="edsl-option-label">Neutral</span>
    </label>
    <label class="edsl-option">
      <input class="edsl-radio" type="radio" value="Agree" />
      <span class="edsl-option-label">Agree</span>
    </label>
    <label class="edsl-option">
      <input class="edsl-radio" type="radio" value="Strongly agree" />
      <span class="edsl-option-label">Strongly agree</span>
    </label>
  </div>
  <p class="edsl-error"></p>
</div>

List

<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

<div class="edsl-question edsl-matrix-question">
  <div class="edsl-question-text">Rate each item.</div>
  <table class="edsl-matrix-table">
    <thead>
      <tr class="edsl-matrix-header-row">
        <th><!-- row label column --></th>
        <th>1</th>
        <th>2</th>
        <th>3</th>
      </tr>
    </thead>
    <tbody>
      <tr class="edsl-matrix-row">
        <td class="edsl-matrix-label-cell">Price</td>
        <td class="edsl-matrix-cell">
          <label>
            <input class="edsl-radio" type="radio" value="1" />
          </label>
        </td>
        <td class="edsl-matrix-cell">
          <label>
            <input class="edsl-radio" type="radio" value="2" />
          </label>
        </td>
        <td class="edsl-matrix-cell">
          <label>
            <input class="edsl-radio" type="radio" value="3" />
          </label>
        </td>
      </tr>
      <tr class="edsl-matrix-row">
        <td class="edsl-matrix-label-cell">Quality</td>
        <!-- … -->
      </tr>
    </tbody>
  </table>
  <p class="edsl-error"></p>
</div>

Multiple choice

When humanize format is radio (default):
<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">
      <input class="edsl-radio" type="radio" value="Apple" />
      <span class="edsl-option-label">Apple</span>
    </label>
    <label class="edsl-option">
      <input class="edsl-radio" type="radio" value="Banana" />
      <span class="edsl-option-label">Banana</span>
    </label>
    <label class="edsl-option">
      <input class="edsl-radio" type="radio" value="Cherry" />
      <span class="edsl-option-label">Cherry</span>
    </label>
  </div>
  <!-- shown only on error -->
  <p class="edsl-error"><svg></svg> Please select an option.</p>
</div>

Multiple choice with other

<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">
      <input class="edsl-radio" type="radio" value="Search engine" />
      <span class="edsl-option-label">Search engine</span>
    </label>
    <label class="edsl-option">
      <input class="edsl-radio" type="radio" value="Friend" />
      <span class="edsl-option-label">Friend</span>
    </label>

    <div class="edsl-other-option">
      <label class="edsl-option">
        <input class="edsl-radio" type="radio" value="Other" />
        <span class="edsl-option-label">Other</span>
      </label>
      <input class="edsl-other-input" type="text" placeholder="Please specify…" />
    </div>
  </div>
  <p class="edsl-error"></p>
</div>

Numerical

When humanize format is input (default):
<div class="edsl-question edsl-numerical-question">
  <div class="edsl-question-text">Enter your age.</div>
  <input class="edsl-input" type="text" />
  <p class="edsl-error"></p>
</div>

Rank

<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>
          <!-- if hasRankCap: -->
          <option value="not-ranked">Not ranked</option>
        </select>
        <span class="edsl-rank-item-label">Item A</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>

Top K

<div class="edsl-question edsl-top-k-question">
  <div class="edsl-question-text">Pick your top 2.</div>
  <div class="edsl-options">
    <div class="edsl-option">
      <input class="edsl-checkbox" type="checkbox" />
      <label class="edsl-option-label">Choice A</label>
    </div>
    <div class="edsl-option">
      <input class="edsl-checkbox" type="checkbox" />
      <label class="edsl-option-label">Choice B</label>
    </div>
    <div class="edsl-option">
      <input class="edsl-checkbox" type="checkbox" />
      <label class="edsl-option-label">Choice C</label>
    </div>
  </div>
  <p class="edsl-error"></p>
</div>

Yes/no

When humanize format is radio (default):
<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">
      <input class="edsl-radio" type="radio" value="Yes" />
      <span class="edsl-option-label">Yes</span>
    </label>
    <label class="edsl-option">
      <input class="edsl-radio" type="radio" value="No" />
      <span class="edsl-option-label">No</span>
    </label>
  </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.
<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>