Skip to main content

Form card

A form card helps me focus and answer a few questions in a big online form.

Form cards enable users to easily progress through complex forms by providing a single-page presentation of important questions and form sections.

Details

  • Extends: USWDS Form
  • Honeycrisp: Form card organism
  • Customization: Styles
  • Modifier: .cfa-form-card, .cfa-form, .cfa-form-card__graphic, .cfa-form-card__heading, .cfa-form-card__help-message, .cfa-form-card__header-alert, .cfa-form-card__content, .cfa-form-card__input-select-group, .cfa-form-card__footer

The Form card is a custom component that extends the USWDS Form. It includes the alert component, form group component, fieldset component, button component, and any other components necessary to create a form. The visual appearance uses design tokens from the Honeycrisp Form card organism. Further customization is applied using the CSS modifiers .cfa-form-card, .cfa-form, .cfa-form-card__graphic, .cfa-form-card__heading, .cfa-form-card__help-message, .cfa-form-card__header-alert, .cfa-form-card__content, .cfa-form-card__input-select-group, .cfa-form-card__footer to add styles defined in a custom stylesheet.

Modifier. A modifier is a class name that applies a variant, type, or extended style customization to modify the component's visual appearance.

Examples

Form card with multiple form groups and fieldsets

Tell us about yourself

Legally as it appears on your I.D.
Legally as it appears on your I.D.
What is your date of birth? (required)
For example January / 1 / 2000
For example, man, woman, or non-binary.
Did you move to the state within the last year?

The HTML for the demonstration above is rendered using context passed to the component's Thymeleaf template fragment. Learn how to include component templates for Thymeleaf and Ruby in the source and usage section.

<main class="cfa-form-card">
  <form class="usa-form cfa-form">
    <svg class="cfa-form-card__graphic usa-icon" aria-hidden="true" focusable="false" role="img">
      <use href="https://codeforamerica.github.io/uswds/assets/img/sprite.svg#person"></use>
    </svg>
    <div>
      <div class="cfa-form-card__heading">
        <h1>Tell us about yourself</h1>
      </div>
      <div class="cfa-form-card__content">
        <div>
          <div>
            <div>
              <div class="usa-form-group cfa-form-group" id="form-group-64955fda9bd4e">
                <label class="usa-label cfa-label" for="input-64955fda9bd4e">
                  <span>What is your first name? <abbr class="usa-hint usa-hint--required cfa-hint text-normal">(required)</abbr>
                  </span>
                </label>
                <div class="usa-hint cfa-hint" id="hint-64955fda9bd4e">Legally as it appears on your I.D.</div>
                <div>
                  <div>
                    <input class="usa-input cfa-input" type="text" id="input-64955fda9bd4e" name="input['64955fda9bd4e']" aria-describedby="hint-64955fda9bd4e">
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
        <div>
          <div>
            <div>
              <div class="usa-form-group cfa-form-group" id="form-group-ea98341e947a5">
                <label class="usa-label cfa-label" for="input-ea98341e947a5">
                  <span>What is your last name? <abbr class="usa-hint usa-hint--required cfa-hint text-normal">(required)</abbr>
                  </span>
                </label>
                <div class="usa-hint cfa-hint" id="hint-ea98341e947a5">Legally as it appears on your I.D.</div>
                <div>
                  <div>
                    <input class="usa-input cfa-input" type="text" id="input-ea98341e947a5" name="input['ea98341e947a5']" aria-describedby="hint-ea98341e947a5">
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
        <div>
          <div>
            <fieldset class="usa-fieldset cfa-fieldset" id="fieldset-1b72c32affdfa">
              <legend class="usa-legend cfa-legend">
                <span>What is your date of birth? <abbr class="usa-hint usa-hint--required cfa-hint text-normal">(required)</abbr>
                </span>
              </legend>
              <div class="usa-hint cfa-hint" id="hint-1b72c32affdfa">For example January / 1 / 2000</div>
              <div class="usa-memorable-date cfa-memorable-date">
                <div>
                  <div class="usa-form-group usa-form-group--month usa-form-group--select" id="form-group-month-1b72c32affdfa">
                    <label class="usa-label cfa-label text-normal" for="month-1b72c32affdfa">
                      <span>Month</span>
                    </label>
                    <div>
                      <select class="usa-select cfa-select" id="month-1b72c32affdfa" name="month['1b72c32affdfa']" aria-describedby="hint-1b72c32affdfa">
                        <option selected="true">Click to select month</option>
                        <option disabled="true">---</option>
                        <option value="1">01 - January</option>
                        <option value="2">02 - February</option>
                        <option value="3">03 - March</option>
                        <option value="4">04 - April</option>
                        <option value="5">05 - May</option>
                        <option value="6">06 - June</option>
                        <option value="7">07 - July</option>
                        <option value="8">08 - August</option>
                        <option value="9">09 - September</option>
                        <option value="10">10 - October</option>
                        <option value="11">11 - November</option>
                        <option value="12">12 - December</option>
                      </select>
                    </div>
                  </div>
                </div>
                <div>
                  <div class="usa-form-group usa-form-group--day" id="form-group-day-1b72c32affdfa">
                    <label class="usa-label cfa-label text-normal" for="day-1b72c32affdfa">
                      <span>Day</span>
                    </label>
                    <div>
                      <div>
                        <input class="usa-input cfa-input" type="text" id="day-1b72c32affdfa" name="day['1b72c32affdfa']" aria-describedby="hint-1b72c32affdfa" pattern="[0-9]*" inputmode="numeric" maxlength="2">
                      </div>
                    </div>
                  </div>
                </div>
                <div>
                  <div class="usa-form-group usa-form-group--year" id="form-group-year-1b72c32affdfa">
                    <label class="usa-label cfa-label text-normal" for="year-1b72c32affdfa">
                      <span>Year</span>
                    </label>
                    <div>
                      <div>
                        <input class="usa-input cfa-input" type="text" id="year-1b72c32affdfa" name="year['1b72c32affdfa']" aria-describedby="hint-1b72c32affdfa" pattern="[0-9]*" inputmode="numeric" maxlength="4">
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </fieldset>
          </div>
        </div>
        <div>
          <div>
            <div>
              <div class="usa-form-group cfa-form-group" id="form-group-a15834a16576c">
                <label class="usa-label cfa-label" for="input-a15834a16576c">
                  <span>Which gender do you identify with?</span>
                </label>
                <div class="usa-hint cfa-hint" id="hint-a15834a16576c">For example, man, woman, or non-binary.</div>
                <div>
                  <div>
                    <input class="usa-input cfa-input" type="text" id="input-a15834a16576c" name="input['a15834a16576c']" aria-describedby="hint-a15834a16576c">
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
        <div>
          <div class="cfa-form-card__input-select-group">
            <fieldset class="usa-fieldset cfa-fieldset">
              <legend class="usa-legend cfa-legend">
                <span>Did you move to the state within the last year?</span>
              </legend>
              <div class="usa-radio cfa-radio">
                <input type="radio" id="radio-59fd47b5804f6" name="radio['226515309f7f']" value="yes" class="usa-radio__input usa-radio__input--tile">
                <label for="radio-59fd47b5804f6" class="usa-radio__label">
                  <span>Yes</span>
                </label>
              </div>
              <div class="usa-radio cfa-radio">
                <input type="radio" id="radio-5fb8884841ce2" name="radio['226515309f7f']" value="no" class="usa-radio__input usa-radio__input--tile">
                <label for="radio-5fb8884841ce2" class="usa-radio__label">
                  <span>No</span>
                </label>
              </div>
            </fieldset>
          </div>
        </div>
      </div>
    </div>
    <div class="cfa-form-card__footer">
      <div>
        <button class="usa-button cfa-form-card__footer-first-button cfa-button usa-button--big" type="submit">
          <span>Continue</span>
        </button>
      </div>
    </div>
  </form>
</main>

Context is the information necessary to configure and render a component template to HTML. It may include plain text strings, HTML, class names, IDs or other HTML attribute values. The context here is defined as JSON but the root attributes are translated to different variable syntaxes for Thymeleaf and Ruby templates. Learn how to pass these variables to each component template in the source and usage section.

{
  "form": {
    "modifier": "cfa-form"
  },
  "graphic": "https://codeforamerica.github.io/uswds/assets/img/sprite.svg#person",
  "header": {
    "heading": {
      "text": "Tell us about yourself"
    }
  },
  "formGroups": [
    {
      "modifier": "cfa-form-group",
      "id": "form-group-64955fda9bd4e",
      "label": {
        "text": "What is your first name? <abbr class=\"usa-hint usa-hint--required cfa-hint text-normal\">(required)</abbr>",
        "for": "input-64955fda9bd4e",
        "modifier": "cfa-label",
        "modifierHint": "cfa-hint"
      },
      "hint": {
        "text": "Legally as it appears on your I.D.",
        "modifier": "cfa-hint",
        "id": "hint-64955fda9bd4e"
      },
      "input": {
        "modifier": "cfa-input",
        "id": "input-64955fda9bd4e",
        "name": "input['64955fda9bd4e']",
        "ariaDescribedby": "hint-64955fda9bd4e",
        "type": "text"
      }
    },
    {
      "modifier": "cfa-form-group",
      "id": "form-group-ea98341e947a5",
      "label": {
        "text": "What is your last name? <abbr class=\"usa-hint usa-hint--required cfa-hint text-normal\">(required)</abbr>",
        "for": "input-ea98341e947a5",
        "modifier": "cfa-label",
        "modifierHint": "cfa-hint"
      },
      "hint": {
        "text": "Legally as it appears on your I.D.",
        "modifier": "cfa-hint",
        "id": "hint-ea98341e947a5"
      },
      "input": {
        "modifier": "cfa-input",
        "id": "input-ea98341e947a5",
        "name": "input['ea98341e947a5']",
        "ariaDescribedby": "hint-ea98341e947a5",
        "type": "text"
      }
    },
    {
      "modifier": "cfa-memorable-date",
      "memorableDate": "true",
      "id": "fieldset-1b72c32affdfa",
      "fieldset": {
        "modifier": "cfa-fieldset",
        "hint": {
          "text": "For example January / 1 / 2000",
          "id": "hint-1b72c32affdfa",
          "modifier": "cfa-hint"
        },
        "legend": {
          "text": "What is your date of birth? <abbr class=\"usa-hint usa-hint--required cfa-hint text-normal\">(required)</abbr>",
          "modifier": "cfa-legend",
          "modifierHint": "cfa-hint"
        }
      },
      "month": {
        "type": "select",
        "modifier": "usa-form-group--month usa-form-group--select",
        "id": "form-group-month-1b72c32affdfa",
        "label": {
          "text": "Month",
          "for": "month-1b72c32affdfa",
          "modifier": "cfa-label text-normal",
          "modifierHint": "cfa-hint"
        },
        "selectEl": {
          "modifier": "cfa-select",
          "id": "month-1b72c32affdfa",
          "name": "month['1b72c32affdfa']",
          "ariaDescribedby": "hint-1b72c32affdfa",
          "default": {
            "label": "Click to select month",
            "selected": "true"
          },
          "options": [
            {
              "label": "---",
              "disabled": "true"
            },
            {
              "value": "1",
              "label": "01 - January"
            },
            {
              "value": "2",
              "label": "02 - February"
            },
            {
              "value": "3",
              "label": "03 - March"
            },
            {
              "value": "4",
              "label": "04 - April"
            },
            {
              "value": "5",
              "label": "05 - May"
            },
            {
              "value": "6",
              "label": "06 - June"
            },
            {
              "value": "7",
              "label": "07 - July"
            },
            {
              "value": "8",
              "label": "08 - August"
            },
            {
              "value": "9",
              "label": "09 - September"
            },
            {
              "value": "10",
              "label": "10 - October"
            },
            {
              "value": "11",
              "label": "11 - November"
            },
            {
              "value": "12",
              "label": "12 - December"
            }
          ]
        }
      },
      "day": {
        "modifier": "usa-form-group--day",
        "id": "form-group-day-1b72c32affdfa",
        "label": {
          "text": "Day",
          "for": "day-1b72c32affdfa",
          "modifier": "cfa-label text-normal",
          "modifierHint": "cfa-hint"
        },
        "input": {
          "modifier": "cfa-input",
          "id": "day-1b72c32affdfa",
          "name": "day['1b72c32affdfa']",
          "type": "text",
          "inputmode": "numeric",
          "maxlength": "2",
          "pattern": "[0-9]*",
          "ariaDescribedby": "hint-1b72c32affdfa"
        }
      },
      "year": {
        "modifier": "usa-form-group--year",
        "id": "form-group-year-1b72c32affdfa",
        "label": {
          "text": "Year",
          "for": "year-1b72c32affdfa",
          "modifier": "cfa-label text-normal",
          "modifierHint": "cfa-hint"
        },
        "input": {
          "modifier": "cfa-input",
          "id": "year-1b72c32affdfa",
          "name": "year['1b72c32affdfa']",
          "type": "text",
          "inputmode": "numeric",
          "minlength": "4",
          "maxlength": "4",
          "pattern": "[0-9]*",
          "ariaDescribedby": "hint-1b72c32affdfa"
        }
      }
    },
    {
      "modifier": "cfa-form-group",
      "id": "form-group-a15834a16576c",
      "label": {
        "text": "Which gender do you identify with?",
        "for": "input-a15834a16576c",
        "modifier": "cfa-label",
        "modifierHint": "cfa-hint"
      },
      "hint": {
        "text": "For example, man, woman, or non-binary.",
        "modifier": "cfa-hint",
        "id": "hint-a15834a16576c"
      },
      "input": {
        "modifier": "cfa-input",
        "id": "input-a15834a16576c",
        "name": "input['a15834a16576c']",
        "ariaDescribedby": "hint-a15834a16576c",
        "type": "text"
      }
    },
    {
      "modifier": "cfa-fieldset",
      "legend": {
        "text": "Did you move to the state within the last year?",
        "modifier": "cfa-legend",
        "modifierHint": "cfa-hint"
      },
      "options": [
        {
          "modifier": "cfa-radio",
          "id": "radio-59fd47b5804f6",
          "name": "radio['226515309f7f']",
          "type": "radio",
          "value": "yes",
          "label": "Yes",
          "input": {
            "modifier": "usa-radio__input--tile"
          }
        },
        {
          "modifier": "cfa-radio",
          "id": "radio-5fb8884841ce2",
          "name": "radio['226515309f7f']",
          "type": "radio",
          "value": "no",
          "label": "No",
          "input": {
            "modifier": "usa-radio__input--tile"
          }
        }
      ]
    }
  ],
  "footer": {
    "submit": [
      {
        "label": "Continue",
        "modifier": "cfa-form-card__footer-first-button cfa-button usa-button--big",
        "type": "submit"
      }
    ]
  }
}
Form card with single question and multi-part text input fieldset

Where are you currently living?

The HTML for the demonstration above is rendered using context passed to the component's Thymeleaf template fragment. Learn how to include component templates for Thymeleaf and Ruby in the source and usage section.

<main class="cfa-form-card">
  <form class="usa-form cfa-form">
    <svg class="cfa-form-card__graphic usa-icon" aria-hidden="true" focusable="false" role="img">
      <use href="https://codeforamerica.github.io/uswds/assets/img/sprite.svg#home"></use>
    </svg>
    <fieldset class="usa-fieldset cfa-fieldset">
      <legend class="cfa-form-card__heading">
        <h1>Where are you currently living?</h1>
      </legend>
      <div class="cfa-form-card__content">
        <div>
          <div>
            <div>
              <div class="usa-form-group cfa-form-group" id="form-group-8ce2c5ea8d548">
                <label class="usa-label cfa-label" for="input-8ce2c5ea8d548">
                  <span>Street address <abbr class="usa-hint usa-hint--required cfa-hint text-normal">(required)</abbr>
                  </span>
                </label>
                <div>
                  <div>
                    <input class="usa-input cfa-input" type="text" id="input-8ce2c5ea8d548" name="input['8ce2c5ea8d548']" autocomplete="address-line1">
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
        <div>
          <div>
            <div>
              <div class="usa-form-group cfa-form-group" id="form-group-d1d9b29acf4d">
                <label class="usa-label cfa-label" for="input-d1d9b29acf4d">
                  <span>Street address line 2</span>
                </label>
                <div>
                  <div>
                    <input class="usa-input cfa-input" type="text" id="input-d1d9b29acf4d" name="input['d1d9b29acf4d']" autocomplete="address-line2">
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
        <div>
          <div>
            <div>
              <div class="usa-form-group cfa-form-group" id="form-group-c90b55286019e">
                <label class="usa-label cfa-label" for="input-c90b55286019e">
                  <span>City <abbr class="usa-hint usa-hint--required cfa-hint text-normal">(required)</abbr>
                  </span>
                </label>
                <div>
                  <div>
                    <input class="usa-input cfa-input" type="text" id="input-c90b55286019e" name="input['c90b55286019e']" autocomplete="address-level2">
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
        <div>
          <div>
            <div>
              <div class="usa-form-group cfa-form-group" id="form-group-b41cd1599c756">
                <label class="usa-label cfa-label" for="input-b41cd1599c756">
                  <span>State, territory, or military post <abbr class="usa-hint usa-hint--required cfa-hint text-normal">(required)</abbr>
                  </span>
                </label>
                <div>
                  <div>
                    <input class="usa-input cfa-input usa-input--sm" type="text" id="input-b41cd1599c756" name="input['b41cd1599c756']" maxlength="2" autocomplete="address-level1">
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
        <div>
          <div>
            <div>
              <div class="usa-form-group cfa-form-group" id="form-group-c725637465b34">
                <label class="usa-label cfa-label" for="input-c725637465b34">
                  <span>ZIP code <abbr class="usa-hint usa-hint--required cfa-hint text-normal">(required)</abbr>
                  </span>
                </label>
                <div>
                  <div>
                    <input class="usa-input cfa-input usa-input--md" type="text" id="input-c725637465b34" name="input['c725637465b34']" pattern="[\d]{5}(-[\d]{4})?" autocomplete="postal-code">
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </fieldset>
    <div class="cfa-form-card__footer">
      <div>
        <button class="usa-button cfa-form-card__footer-first-button cfa-button usa-button--big" type="submit">
          <span>Continue</span>
        </button>
      </div>
    </div>
  </form>
</main>

Context is the information necessary to configure and render a component template to HTML. It may include plain text strings, HTML, class names, IDs or other HTML attribute values. The context here is defined as JSON but the root attributes are translated to different variable syntaxes for Thymeleaf and Ruby templates. Learn how to pass these variables to each component template in the source and usage section.

{
  "form": {
    "modifier": "cfa-form"
  },
  "graphic": "https://codeforamerica.github.io/uswds/assets/img/sprite.svg#home",
  "header": {
    "heading": {
      "text": "Where are you currently living?"
    }
  },
  "fieldset": {
    "modifier": "cfa-fieldset",
    "formGroups": [
      {
        "modifier": "cfa-form-group",
        "id": "form-group-8ce2c5ea8d548",
        "label": {
          "text": "Street address <abbr class=\"usa-hint usa-hint--required cfa-hint text-normal\">(required)</abbr>",
          "for": "input-8ce2c5ea8d548",
          "modifier": "cfa-label"
        },
        "input": {
          "modifier": "cfa-input",
          "id": "input-8ce2c5ea8d548",
          "name": "input['8ce2c5ea8d548']",
          "type": "text",
          "autocomplete": "address-line1"
        }
      },
      {
        "modifier": "cfa-form-group",
        "id": "form-group-d1d9b29acf4d",
        "label": {
          "text": "Street address line 2",
          "for": "input-d1d9b29acf4d",
          "modifier": "cfa-label"
        },
        "input": {
          "modifier": "cfa-input",
          "id": "input-d1d9b29acf4d",
          "name": "input['d1d9b29acf4d']",
          "type": "text",
          "autocomplete": "address-line2"
        }
      },
      {
        "modifier": "cfa-form-group",
        "id": "form-group-c90b55286019e",
        "label": {
          "text": "City <abbr class=\"usa-hint usa-hint--required cfa-hint text-normal\">(required)</abbr>",
          "for": "input-c90b55286019e",
          "modifier": "cfa-label"
        },
        "input": {
          "modifier": "cfa-input",
          "id": "input-c90b55286019e",
          "name": "input['c90b55286019e']",
          "type": "text",
          "autocomplete": "address-level2"
        }
      },
      {
        "modifier": "cfa-form-group",
        "id": "form-group-b41cd1599c756",
        "label": {
          "text": "State, territory, or military post <abbr class=\"usa-hint usa-hint--required cfa-hint text-normal\">(required)</abbr>",
          "for": "input-b41cd1599c756",
          "modifier": "cfa-label"
        },
        "input": {
          "modifier": "cfa-input usa-input--sm",
          "id": "input-b41cd1599c756",
          "name": "input['b41cd1599c756']",
          "type": "text",
          "maxlength": "2",
          "autocomplete": "address-level1"
        }
      },
      {
        "modifier": "cfa-form-group",
        "id": "form-group-c725637465b34",
        "label": {
          "text": "ZIP code <abbr class=\"usa-hint usa-hint--required cfa-hint text-normal\">(required)</abbr>",
          "for": "input-c725637465b34",
          "modifier": "cfa-label"
        },
        "input": {
          "modifier": "cfa-input usa-input--md",
          "id": "input-c725637465b34",
          "name": "input['c725637465b34']",
          "type": "text",
          "pattern": "[\\d]{5}(-[\\d]{4})?",
          "autocomplete": "postal-code"
        }
      }
    ]
  },
  "footer": {
    "submit": [
      {
        "label": "Continue",
        "modifier": "cfa-form-card__footer-first-button cfa-button usa-button--big",
        "type": "submit"
      }
    ]
  }
}
Form card with single question, alert, and radios fieldset

Confirm your address

We couldn't find your address. To make sure you get mail from the county, you may edit your address or keep going. Alternatively, click here to look up your county information.

The HTML for the demonstration above is rendered using context passed to the component's Thymeleaf template fragment. Learn how to include component templates for Thymeleaf and Ruby in the source and usage section.

<main class="cfa-form-card">
  <form class="usa-form cfa-form">
    <fieldset class="usa-fieldset cfa-fieldset">
      <legend class="cfa-form-card__heading">
        <h1 id="aria-lb-4880a3b0d60c1">Confirm your address</h1>
      </legend>
      <div>
        <div class="usa-alert cfa-form-card__header-alert cfa-alert usa-alert--warning" role="region" aria-labelledby="aria-lb-4880a3b0d60c1">
          <div class="usa-alert__body">
            <p class="usa-alert__text">We couldn't find your address. To make sure you get mail from the county, you may edit your address or keep going. <a href="#">Alternatively, click here to look up your county information</a>.</p>
          </div>
        </div>
      </div>
      <div class="cfa-form-card__content">
        <div>
          <div class="cfa-form-card__input-select-group">
            <div class="usa-radio cfa-radio">
              <input type="radio" id="radio-567be5eecd3d5" name="radio['e99d8868d5bbe']" value="suggested-address" checked="true" class="usa-radio__input usa-radio__input--tile">
              <label for="radio-567be5eecd3d5" class="usa-radio__label">
                <span>Suggested address</span>
                <span class="usa-radio__label-description">4918 Webster St., Apt 2
                  <br> Oakland, CA
                  <br> 94609
                </span>
              </label>
            </div>
            <div class="usa-radio cfa-radio">
              <input type="radio" id="radio-4f25e0a3bd532" name="radio['e99d8868d5bbe']" value="address-you-entered" class="usa-radio__input usa-radio__input--tile">
              <label for="radio-4f25e0a3bd532" class="usa-radio__label">
                <span>Address you entered</span>
                <span class="usa-radio__label-description">4918 Webster Street
                  <br> Apt 2
                  <br> Oakland, CA
                  <br> 94609
                </span>
              </label>
            </div>
          </div>
        </div>
      </div>
    </fieldset>
    <div class="cfa-form-card__footer">
      <div>
        <button class="usa-button cfa-form-card__footer-first-button cfa-button usa-button--big" type="submit">
          <span>Continue</span>
        </button>
      </div>
    </div>
  </form>
</main>

Context is the information necessary to configure and render a component template to HTML. It may include plain text strings, HTML, class names, IDs or other HTML attribute values. The context here is defined as JSON but the root attributes are translated to different variable syntaxes for Thymeleaf and Ruby templates. Learn how to pass these variables to each component template in the source and usage section.

{
  "form": {
    "modifier": "cfa-form"
  },
  "header": {
    "heading": {
      "id": "aria-lb-4880a3b0d60c1",
      "text": "Confirm your address"
    },
    "alert": {
      "modifier": "cfa-form-card__header-alert cfa-alert usa-alert--warning",
      "role": "region",
      "labelledby": "aria-lb-4880a3b0d60c1",
      "text": "We couldn't find your address. To make sure you get mail from the county, you may edit your address or keep going. <a href=\"#\">Alternatively, click here to look up your county information</a>."
    }
  },
  "fieldset": {
    "modifier": "cfa-fieldset",
    "formGroups": [
      {
        "options": [
          {
            "modifier": "cfa-radio",
            "id": "radio-567be5eecd3d5",
            "name": "radio['e99d8868d5bbe']",
            "type": "radio",
            "value": "suggested-address",
            "label": "Suggested address",
            "description": "4918 Webster St., Apt 2 <br> Oakland, CA <br> 94609",
            "checked": "true",
            "input": {
              "modifier": "usa-radio__input--tile"
            }
          },
          {
            "modifier": "cfa-radio",
            "id": "radio-4f25e0a3bd532",
            "name": "radio['e99d8868d5bbe']",
            "type": "radio",
            "value": "address-you-entered",
            "label": "Address you entered",
            "description": "4918 Webster Street <br> Apt 2 <br> Oakland, CA <br> 94609",
            "input": {
              "modifier": "usa-radio__input--tile"
            }
          }
        ]
      }
    ]
  },
  "footer": {
    "submit": [
      {
        "label": "Continue",
        "modifier": "cfa-form-card__footer-first-button cfa-button usa-button--big",
        "type": "submit"
      }
    ]
  }
}
Form card with single question, continue, and skip links

Are you sure you want to leave your phone number blank?

A caseworker may need to contact you by phone about your application. If you don't have a phone number, you can enter a friend or family member's phone number instead.

The HTML for the demonstration above is rendered using context passed to the component's Thymeleaf template fragment. Learn how to include component templates for Thymeleaf and Ruby in the source and usage section.

<main class="cfa-form-card">
  <form class="usa-form cfa-form">
    <svg class="cfa-form-card__graphic usa-icon" aria-hidden="true" focusable="false" role="img">
      <use href="https://codeforamerica.github.io/uswds/assets/img/sprite.svg#phone"></use>
    </svg>
    <div>
      <div class="cfa-form-card__heading">
        <h1>Are you sure you want to leave your phone number blank?</h1>
      </div>
      <div class="cfa-form-card__content">
        <p>A caseworker may need to contact you by phone about your application. If you don't have a phone number, you can enter a friend or family member's phone number instead.</p>
      </div>
    </div>
    <div class="cfa-form-card__footer">
      <div>
        <a class="usa-button cfa-form-card__footer-first-button cfa-button usa-button--big" href="#">
          <span>Add a phone number</span>
        </a>
      </div>
      <div>
        <a class="usa-button cfa-button usa-button--big usa-button--outline" href="#">
          <span>Continue without it</span>
        </a>
      </div>
    </div>
  </form>
</main>

Context is the information necessary to configure and render a component template to HTML. It may include plain text strings, HTML, class names, IDs or other HTML attribute values. The context here is defined as JSON but the root attributes are translated to different variable syntaxes for Thymeleaf and Ruby templates. Learn how to pass these variables to each component template in the source and usage section.

{
  "form": {
    "modifier": "cfa-form"
  },
  "graphic": "https://codeforamerica.github.io/uswds/assets/img/sprite.svg#phone",
  "header": {
    "heading": {
      "text": "Are you sure you want to leave your phone number blank?"
    }
  },
  "content": "<p>A caseworker may need to contact you by phone about your application. If you don't have a phone number, you can enter a friend or family member's phone number instead.</p>",
  "footer": {
    "submit": [
      {
        "label": "Add a phone number",
        "modifier": "cfa-form-card__footer-first-button cfa-button usa-button--big",
        "href": "#"
      }
    ],
    "skip": [
      {
        "label": "Continue without it",
        "modifier": "cfa-button usa-button--big usa-button--outline",
        "href": "#"
      }
    ]
  }
}
Form card with single question, yes, and no links

Do you live with any of these people?

  • Your spouse
  • Your children
  • Other family members
  • Your domestic partner

The HTML for the demonstration above is rendered using context passed to the component's Thymeleaf template fragment. Learn how to include component templates for Thymeleaf and Ruby in the source and usage section.

<main class="cfa-form-card">
  <form class="usa-form cfa-form">
    <div>
      <div class="cfa-form-card__heading">
        <h1>Do you live with any of these people?</h1>
      </div>
      <div class="cfa-form-card__content">
        <ul>
          <li>Your spouse</li>
          <li>Your children</li>
          <li>Other family members</li>
          <li>Your domestic partner</li>
        </ul>
      </div>
    </div>
    <div class="cfa-form-card__footer">
      <div>
        <a class="usa-button cfa-button cfa-button--yes usa-button--big usa-button--outline" href="#">
          <svg class="usa-icon" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" role="img">
            <path d="M3.5 9.42857L0 13L8 22L22 3.5L18 0L7.5 14L3.5 9.42857Z" fill="inherit"></path>
          </svg>
          <span>Yes</span>
        </a>
        <a class="usa-button cfa-button cfa-button--no usa-button--big usa-button--outline " href="#">
          <svg class="usa-icon" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" role="img">
            <path d="M14.667 11.0009L22 3.66696L18.3335 0L11 7.33392L3.66696 0.00088L0 3.66696L7.33348 11L0 18.3339L3.6674 22L11.0004 14.667L18.3335 22L22 18.3339L14.667 11.0009Z" fill="inherit"></path>
          </svg>
          <span>No</span>
        </a>
      </div>
    </div>
  </form>
</main>

Context is the information necessary to configure and render a component template to HTML. It may include plain text strings, HTML, class names, IDs or other HTML attribute values. The context here is defined as JSON but the root attributes are translated to different variable syntaxes for Thymeleaf and Ruby templates. Learn how to pass these variables to each component template in the source and usage section.

{
  "form": {
    "modifier": "cfa-form"
  },
  "header": {
    "heading": {
      "text": "Do you live with any of these people?"
    }
  },
  "content": "<ul><li>Your spouse</li><li>Your children</li><li>Other family members</li><li>Your domestic partner</li></ul>",
  "footer": {
    "group": [
      {
        "label": "Yes",
        "check": true,
        "modifier": "cfa-button cfa-button--yes usa-button--big usa-button--outline",
        "href": "#"
      },
      {
        "label": "No",
        "cross": true,
        "modifier": "cfa-button cfa-button--no usa-button--big usa-button--outline ",
        "href": "#"
      }
    ]
  }
}
Form card for uploading documents

Add your files or photos

Please submit proof of each of the following:

  • Your identity.
    For each person, we need things like a photo ID (like a driver's license or passport), birth certificate, adoption papers, or naturalization certificate.

  • Your job and income.
    For work, we might ask for your latest tax returns, current pay stubs, a letter from your boss with info about how much you earn and how often you work, W-2 forms, or records if you work for yourself. We need this for everyone in your home.

  • Money in the bank and other valuable assets.
    Having these things can affect whether you can get help with childcare and food benefits faster.

  • Where you live and who lives there.
    This can include your lease, rental agreement, recent rent receipts with your address, a statement from your landlord (who can't be a relative), or mortgage papers.

  • Money you spend on your home or shelter and bills.
    For example, we might need to see bills for things like electricity, gas, water, internet, phone, sewer, and garbage collection. Documentation for shelter costs may be similar to requirements for proof of where you live (lease or rental agreements).

The following proof may be requested depending on your circumstances:

  • Education and training.
    This could include diplomas, school records, transcripts, certificates, or proof of your work experience if you're getting help from the Temporary Assistance for Needy Families (TANF) program.

  • Marriage or relationship status.
    These documents could be things like your marriage certificate, a document that says you're separated, or a divorce decree if you've been divorced.

  • Your Social Security number.
    You can do this by sharing your Social Security card or any official papers you've received from the Social Security Administration.

  • Your status in the United States.
    You can show us this with documents like your birth certificate, records from your military service, or a naturalization certificate if you became a citizen. If you're not a U.S. citizen, we'll need to know that too.

  • Disability.
    Some examples include Medical records or doctor's statements.

  • You get child support money.
    You can show us this with things like papers from family court, a statement from the person paying the support, check stubs, or official letters from the agency that's making sure the support is paid.

  • Money from other support programs.
    To prove this, you can use official papers from the program that's helping you, awards, letters, pay stubs, checks, certificates, or letters.

  • Health insurance you may have.
    This could be your insurance card, a paper from your insurance company, or your Medicare card if you have one.

  • Details about any parent (or step-parent) who doesn't live with you.
    The information we need is similar to what we've already detailed such as, proof of identity, Social Security number, job information, or marriage documents.

You can provide any of these documents as images or PDFs by…

  • … taking photos using your phone, or
  • … taking a screenshot on your phone or computer, or
  • … selecting files stored on your phone or computer.

We accept any file with a name that ends in .pdf, .jpeg, .jpg, .png, .bmp, .gif, .doc, .docx, .odt, .ods, or .odp. Each file is limited to 20 MB, and a maximum of 20 files are allowed.

The HTML for the demonstration above is rendered using context passed to the component's Thymeleaf template fragment. Learn how to include component templates for Thymeleaf and Ruby in the source and usage section.

<main class="cfa-form-card">
  <form class="usa-form cfa-form">
    <fieldset class="usa-fieldset cfa-fieldset">
      <legend class="cfa-form-card__heading">
        <h1 id="label-0e3c442269865">Add your files or photos</h1>
      </legend>
      <div class="cfa-form-card__details">
        <div>
          <div class="cfa-details">
            <button type="button" class="cfa-details__summary" data-js="details" data-aria-controls="aria-c-ee3a9211edd5b">
              <span>Review document list</span>
              <svg class="usa-icon" aria-hidden="true" focusable="false" role="img">
                <use href="https://codeforamerica.github.io/uswds/assets/img/sprite.svg#chevron_right"></use>
              </svg>
            </button>
            <div class="cfa-details__content" id="aria-c-ee3a9211edd5b">
              <p>
                <strong>Please submit proof of each of the following:</strong>
              </p>
              <ul>
                <li>
                  <p>
                    <strong>Your identity</strong>.
                    <br> For each person, we need things like a photo ID (like a driver's license or passport), birth certificate, adoption papers, or naturalization certificate.
                  </p>
                </li>
                <li>
                  <p>
                    <strong>Your job and income</strong>.
                    <br> For work, we might ask for your latest tax returns, current pay stubs, a letter from your boss with info about how much you earn and how often you work, W-2 forms, or records if you work for yourself. We need this for everyone in your home.
                  </p>
                </li>
                <li>
                  <p>
                    <strong>Money in the bank and other valuable assets</strong>.
                    <br> Having these things can affect whether you can get help with childcare and food benefits faster.
                  </p>
                </li>
                <li>
                  <p>
                    <strong>Where you live and who lives there</strong>.
                    <br> This can include your lease, rental agreement, recent rent receipts with your address, a statement from your landlord (who can't be a relative), or mortgage papers.
                  </p>
                </li>
                <li>
                  <p>
                    <strong>Money you spend on your home or shelter and bills</strong>.
                    <br> For example, we might need to see bills for things like electricity, gas, water, internet, phone, sewer, and garbage collection. Documentation for shelter costs may be similar to requirements for proof of where you live (lease or rental agreements).
                  </p>
                </li>
              </ul>
              <p>
                <strong>The following proof may be requested depending on your circumstances:</strong>
              </p>
              <ul>
                <li>
                  <p>
                    <strong>Education and training</strong>.
                    <br> This could include diplomas, school records, transcripts, certificates, or proof of your work experience if you're getting help from the Temporary Assistance for Needy Families (TANF) program.
                  </p>
                </li>
                <li>
                  <p>
                    <strong>Marriage or relationship status</strong>.
                    <br> These documents could be things like your marriage certificate, a document that says you're separated, or a divorce decree if you've been divorced.
                  </p>
                </li>
                <li>
                  <p>
                    <strong>Your Social Security number</strong>.
                    <br> You can do this by sharing your Social Security card or any official papers you've received from the Social Security Administration.
                  </p>
                </li>
                <li>
                  <p>
                    <strong>Your status in the United States</strong>.
                    <br> You can show us this with documents like your birth certificate, records from your military service, or a naturalization certificate if you became a citizen. If you're not a U.S. citizen, we'll need to know that too.
                  </p>
                </li>
                <li>
                  <p>
                    <strong>Disability</strong>.
                    <br> Some examples include Medical records or doctor's statements.
                  </p>
                </li>
                <li>
                  <p>
                    <strong>You get child support money</strong>.
                    <br> You can show us this with things like papers from family court, a statement from the person paying the support, check stubs, or official letters from the agency that's making sure the support is paid.
                  </p>
                </li>
                <li>
                  <p>
                    <strong>Money from other support programs</strong>.
                    <br> To prove this, you can use official papers from the program that's helping you, awards, letters, pay stubs, checks, certificates, or letters.
                  </p>
                </li>
                <li>
                  <p>
                    <strong>Health insurance you may have</strong>.
                    <br> This could be your insurance card, a paper from your insurance company, or your Medicare card if you have one.
                  </p>
                </li>
                <li>
                  <p>
                    <strong>Details about any parent (or step-parent) who doesn't live with you</strong>.
                    <br> The information we need is similar to what we've already detailed such as, proof of identity, Social Security number, job information, or marriage documents.
                  </p>
                </li>
              </ul>
            </div>
          </div>
        </div>
        <div>
          <div class="cfa-details">
            <button type="button" class="cfa-details__summary" data-js="details" data-aria-controls="aria-c-ef2007838b5ee">
              <span>Review tips for adding documents</span>
              <svg class="usa-icon" aria-hidden="true" focusable="false" role="img">
                <use href="https://codeforamerica.github.io/uswds/assets/img/sprite.svg#chevron_right"></use>
              </svg>
            </button>
            <div class="cfa-details__content" id="aria-c-ef2007838b5ee">
              <p>You can provide any of these documents as images or PDFs by…</p>
              <ul>
                <li>… taking photos using your phone, or</li>
                <li>… taking a screenshot on your phone or computer, or</li>
                <li>… selecting files stored on your phone or computer.</li>
              </ul>
              <p>We accept any file with a name that ends in .pdf, .jpeg, .jpg, .png, .bmp, .gif, .doc, .docx, .odt, .ods, or .odp. Each file is limited to <strong>20 MB</strong>, and a <strong>maximum of 20 files</strong> are allowed.</p>
            </div>
          </div>
        </div>
      </div>
      <div class="cfa-form-card__content">
        <div>
          <div>
            <div class="usa-form-group cfa-form-group cfa-file-selector" data-js="file-selector" id="dropzone-0e3c442269865">
              <div data-dropzone="uploads">
                <span class="usa-error-message" aria-hidden="true" data-dropzone="input-error-message"></span>
                <div class="usa-file-input cfa-file-input">
                  <div class="usa-file-input__target margin-bottom-3" data-dropzone="drag-and-drop-region">
                    <div class="usa-file-input__box"></div>
                    <div class="usa-file-input__instructions">
                      <div class="usa-hint cfa-hint" aria-hidden="true" id="hint-0e3c442269865">
                        <span class="usa-file-input__choose">Select or drop files here</span>
                      </div>
                      <div class="dz-message" data-dropzone="upload-button">
                        <button class="usa-button cfa-button circle-9 padding-0 margin-0" type="button" data-dropzone="button" aria-hidden="true" focusable="false" tabindex="-1">
                          <svg class="usa-icon square-7 margin-bottom-neg-2px" aria-hidden="true" focusable="false" tabindex="-1">
                            <use href="https://codeforamerica.github.io/uswds/assets/img/sprite.svg#add"></use>
                          </svg>
                        </button>
                      </div>
                    </div>
                    <input class="usa-file-input__input" type="file" data-dropzone="fallback" id="input-0e3c442269865" name="input['0e3c442269865']" aria-labelledby="label-0e3c442269865" aria-describedby="hint-0e3c442269865" accept=".jpeg, .jpg, .png, .pdf, .bmp, .gif, .doc, .docx, .odt, .ods, .odp" multiple="multiple">
                    <div data-dropzone="hidden-input-container"></div>
                  </div>
                </div>
              </div>
              <!--/* @hidden       "true"  Visually hides element */-->
              <!--/* @aria-hidden  "true"  Hides element from the accessibility API */-->
              <div data-dropzone="preview" hidden="true" aria-hidden="true">
                <h3 class="cfa-file-selector__preview-header" data-dropzone="preview-header" id="aria-db-c0df2dac90d5c"> Your documents. <span data-dropzone="preview-number">0</span>
                  <span data-dropzone="preview-text">uploaded</span>
                  <span>(<span>20 max</span>)</span>
                </h3>
                <ul class="add-list-reset" role="list" data-dropzone="preview-container" aria-describedby="aria-db-c0df2dac90d5c">
                  <!--/* Use previewTemplate to add a custom preview template  */-->
                  <!--/* @data-dropzone  "remove"  removes contents before passing to Dropzone */-->
                  <!--/* Dropzone will modify or replace the contents of this element */-->
                  <!--/* @data-dropzone  "remove"  removes contents before passing to Dropzone */-->
                  <li class="cfa-file-selector__preview dz-image-preview" data-dropzone="preview-template">
                    <div class="cfa-file-selector__details">
                      <div class="cfa-file-selector__thumbnail" data-dropzone="thumbnail">
                        <div class="cfa-file-selector__progress">
                          <span class="cfa-file-selector__progress-bar" data-dz-uploadprogress="keep"></span>
                        </div>
                        <svg class="usa-icon cfa-file-selector__icon-error" aria-hidden="true" focusable="false" role="img">
                          <use href="https://codeforamerica.github.io/uswds/assets/img/sprite.svg#warning"></use>
                        </svg>
                        <svg class="usa-icon cfa-file-selector__icon-default" aria-hidden="true" focusable="false" role="img">
                          <use href="https://codeforamerica.github.io/uswds/assets/img/sprite.svg#file_present"></use>
                        </svg>
                        <img class="cfa-file-selector__img" data-dropzone="img" data-dz-thumbnail="keep" aria-hidden="true" alt="preview-template__filename--testing-truncated-text.ext">
                      </div>
                      <div class="cfa-file-selector__file">
                        <div class="cfa-file-selector__filename" data-dz-name="keep">
                          <span class="cfa-file-selector__filename-name" aria-hidden="true">preview-template__filename--testing-truncated-text</span>
                          <span class="cfa-file-selector__filename-ext" aria-hidden="true">.ext</span>
                        </div>
                        <span class="cfa-file-selector__error-message usa-error-message" aria-live="polite" aria-atomic="true" data-dz-errormessage="keep"> Message </span>
                        <div>
                          <span class="font-body-2xs" title="File size">
                            <span class="usa-sr-only">File size, </span>
                            <span class="font-body-2xs" data-dz-size="keep">
                              <strong>99</strong> MB
                            </span>
                            <span>
                              <span class="text-base-lighter padding-inline-x-1 display-none mobile:display-inline-block" aria-hidden="true">|</span>
                              <button type="button" class="usa-button cfa-button cfa-button--danger usa-button--unstyled font-body-2xs" aria-hidden="true" focusable="false" data-dropzone="file-remove" data-dz-remove="keep">
                                <span data-dropzone="file-remove-label">remove</span>
                                <span class="usa-sr-only" data-dz-name="keep">preview-template__filename--testing-truncated-text.ext</span>
                              </button>
                              <!--/* @data-dropzone  "remove"  removes contents before passing to Dropzone. These are used to test the various states for the thumbnail upload. */-->
                              <span data-dropzone="remove">
                                <span class="text-base-lighter padding-inline-x-1 display-none mobile:display-inline-block" aria-hidden="true">|</span>
                                <button type="button" class="usa-button cfa-button usa-button--unstyled font-body-2xs" aria-hidden="true" focusable="false" data-dropzone="toggle-preview-state" data-dropzone-preview-state="cfa-file-selector__preview dz-image-preview">base</button>
                                <span class="text-base-lighter padding-inline-x-1 display-none mobile:display-inline-block" aria-hidden="true">|</span>
                                <button type="button" class="usa-button cfa-button usa-button--unstyled font-body-2xs" aria-hidden="true" focusable="false" data-dropzone="toggle-preview-state" data-dropzone-preview-state="cfa-file-selector__preview dz-image-preview dz-processing">processing</button>
                                <span class="text-base-lighter padding-inline-x-1 display-none mobile:display-inline-block" aria-hidden="true">|</span>
                                <button type="button" class="usa-button cfa-button usa-button--unstyled font-body-2xs" aria-hidden="true" focusable="false" data-dropzone="toggle-preview-state" data-dropzone-preview-state="cfa-file-selector__preview dz-image-preview dz-processing dz-complete">complete</button>
                                <span class="text-base-lighter padding-inline-x-1 display-none mobile:display-inline-block" aria-hidden="true">|</span>
                                <button type="button" class="usa-button cfa-button usa-button--unstyled font-body-2xs" aria-hidden="true" focusable="false" data-dropzone="toggle-preview-state" data-dropzone-preview-state="cfa-file-selector__preview dz-image-preview dz-processing dz-success dz-complete">success</button>
                                <span class="text-base-lighter padding-inline-x-1 display-none mobile:display-inline-block" aria-hidden="true">|</span>
                                <button type="button" class="usa-button cfa-button usa-button--unstyled font-body-2xs" aria-hidden="true" focusable="false" data-dropzone="toggle-preview-state" data-dropzone-preview-state="cfa-file-selector__preview dz-image-preview dz-processing dz-success dz-complete dz-default">default</button>
                                <span class="text-base-lighter padding-inline-x-1 display-none mobile:display-inline-block" aria-hidden="true">|</span>
                                <button type="button" class="usa-button cfa-button usa-button--unstyled font-body-2xs" aria-hidden="true" focusable="false" data-dropzone="toggle-preview-state" data-dropzone-preview-state="cfa-file-selector__preview dz-image-preview dz-processing dz-error dz-complete">error</button>
                              </span>
                            </span>
                          </span>
                        </div>
                      </div>
                    </div>
                  </li>
                </ul>
              </div>
              <!--/* Strings used by the UploadDocument script will be pulled from this element */-->
              <!--/* @hidden         "true"    Visually hides element */-->
              <!--/* @aria-hidden    "true"    Hides element from the accessibility API */-->
              <!--/* @data-dropzone  "remove"  removes contents before passing to Dropzone */-->
              <div hidden="true" aria-hidden="true" data-dropzone="remove">
                <p data-dropzone="dict" data-dropzone-dict="fileTooBig">Sorry, we can't accept files larger than 20 MB. Please, remove this file, make it smaller, then, try again.</p>
                <p data-dropzone="dict" data-dropzone-dict="maxFiles">You have uploaded the maximum number of 20 files. You will have the opportunity to add more later.</p>
                <p data-dropzone="dict" data-dropzone-dict="maxFilesExceeded">Sorry, we can't accept this file. You have uploaded the maximum number of 20 files. You will have the opportunity to add more later.</p>
                <p data-dropzone="dict" data-dropzone-dict="invalidFileType">Sorry, we can't accept this type of file. Please, remove this file, then, try another file that ends in .jpeg, .jpg, .png, .pdf, .bmp, .gif, .doc, .docx, .odt, .ods, or .odp.</p>
                <p data-dropzone="dict" data-dropzone-dict="responseError">Sorry, there was an error on our end. Please, remove this file and try again. If the error continues please try again later.</p>
              </div>
            </div>
          </div>
        </div>
      </div>
    </fieldset>
  </form>
</main>

Context is the information necessary to configure and render a component template to HTML. It may include plain text strings, HTML, class names, IDs or other HTML attribute values. The context here is defined as JSON but the root attributes are translated to different variable syntaxes for Thymeleaf and Ruby templates. Learn how to pass these variables to each component template in the source and usage section.

{
  "form": {
    "modifier": "cfa-form"
  },
  "header": {
    "heading": {
      "id": "label-0e3c442269865",
      "text": "Add your files or photos"
    },
    "details": [
      {
        "summary": "Review document list",
        "icon": "https://codeforamerica.github.io/uswds/assets/img/sprite.svg#chevron_right",
        "controls": "aria-c-ee3a9211edd5b",
        "body": "<p><strong>Please submit proof of each of the following:</strong></p><ul><li><p><strong>Your identity</strong>. <br> For each person, we need things like a photo ID (like a driver's license or passport), birth certificate, adoption papers, or naturalization certificate.</p></li><li><p><strong>Your job and income</strong>. <br> For work, we might ask for your latest tax returns, current pay stubs, a letter from your boss with info about how much you earn and how often you work, W-2 forms, or records if you work for yourself. We need this for everyone in your home.</p></li><li><p><strong>Money in the bank and other valuable assets</strong>. <br> Having these things can affect whether you can get help with childcare and food benefits faster.</p></li><li><p><strong>Where you live and who lives there</strong>. <br> This can include your lease, rental agreement, recent rent receipts with your address, a statement from your landlord (who can't be a relative), or mortgage papers.</p></li><li><p><strong>Money you spend on your home or shelter and bills</strong>. <br> For example, we might need to see bills for things like electricity, gas, water, internet, phone, sewer, and garbage collection. Documentation for shelter costs may be similar to requirements for proof of where you live (lease or rental agreements).</p></li></ul><p><strong>The following proof may be requested depending on your circumstances:</strong></p><ul><li><p><strong>Education and training</strong>. <br> This could include diplomas, school records, transcripts, certificates, or proof of your work experience if you're getting help from the Temporary Assistance for Needy Families (TANF) program.</p></li><li><p><strong>Marriage or relationship status</strong>. <br> These documents could be things like your marriage certificate, a document that says you're separated, or a divorce decree if you've been divorced.</p></li><li><p><strong>Your Social Security number</strong>. <br> You can do this by sharing your Social Security card or any official papers you've received from the Social Security Administration.</p></li><li><p><strong>Your status in the United States</strong>. <br> You can show us this with documents like your birth certificate, records from your military service, or a naturalization certificate if you became a citizen. If you're not a U.S. citizen, we'll need to know that too.</p></li><li><p><strong>Disability</strong>. <br> Some examples include Medical records or doctor's statements.</p></li><li><p><strong>You get child support money</strong>. <br> You can show us this with things like papers from family court, a statement from the person paying the support, check stubs, or official letters from the agency that's making sure the support is paid.</p></li><li><p><strong>Money from other support programs</strong>. <br> To prove this, you can use official papers from the program that's helping you, awards, letters, pay stubs, checks, certificates, or letters.</p></li><li><p><strong>Health insurance you may have</strong>. <br> This could be your insurance card, a paper from your insurance company, or your Medicare card if you have one.</p></li><li><p><strong>Details about any parent (or step-parent) who doesn't live with you</strong>. <br> The information we need is similar to what we've already detailed such as, proof of identity, Social Security number, job information, or marriage documents.</p></li></ul>"
      },
      {
        "summary": "Review tips for adding documents",
        "icon": "https://codeforamerica.github.io/uswds/assets/img/sprite.svg#chevron_right",
        "controls": "aria-c-ef2007838b5ee",
        "body": "<p>You can provide any of these documents as images or PDFs by…</p><ul><li>… taking photos using your phone, or</li><li>… taking a screenshot on your phone or computer, or</li><li>… selecting files stored on your phone or computer.</li></ul><p>We accept any file with a name that ends in .pdf, .jpeg, .jpg, .png, .bmp, .gif, .doc, .docx, .odt, .ods, or .odp. Each file is limited to <strong>20 MB</strong>, and a <strong>maximum of 20 files</strong> are allowed.</p>"
      }
    ]
  },
  "fieldset": {
    "modifier": "cfa-fieldset",
    "formGroups": [
      {
        "modifier": "",
        "id": "dropzone-0e3c442269865",
        "fileInput": {
          "modifier": "cfa-form-group cfa-file-input",
          "id": "form-group-0e3c442269865",
          "hint": {
            "text": "<span class=\"usa-file-input__choose\">Select or drop files here</span>",
            "modifier": "cfa-hint",
            "id": "hint-0e3c442269865"
          },
          "input": {
            "modifier": "usa-file-input cfa-input cfa-file-input__input",
            "id": "input-0e3c442269865",
            "name": "input['0e3c442269865']",
            "ariaLabelledby": "label-0e3c442269865",
            "ariaDescribedby": "hint-0e3c442269865",
            "type": "file",
            "accept": ".jpeg, .jpg, .png, .pdf, .bmp, .gif, .doc, .docx, .odt, .ods, .odp",
            "multiple": "multiple",
            "required": "true"
          },
          "button": {
            "icon": "https://codeforamerica.github.io/uswds/assets/img/sprite.svg#add"
          }
        },
        "previewHeader": {
          "id": "aria-db-c0df2dac90d5c"
        },
        "defaultPreviewTemplate": {
          "error": {
            "icon": "https://codeforamerica.github.io/uswds/assets/img/sprite.svg#warning"
          },
          "thumbnail": {
            "default": "https://codeforamerica.github.io/uswds/assets/img/sprite.svg#file_present"
          }
        },
        "dict": [
          {
            "key": "fileTooBig",
            "string": "Sorry, we can't accept files larger than 20 MB. Please, remove this file, make it smaller, then, try again."
          },
          {
            "key": "maxFiles",
            "string": "You have uploaded the maximum number of 20 files. You will have the opportunity to add more later."
          },
          {
            "key": "maxFilesExceeded",
            "string": "Sorry, we can't accept this file. You have uploaded the maximum number of 20 files. You will have the opportunity to add more later."
          },
          {
            "key": "invalidFileType",
            "string": "Sorry, we can't accept this type of file. Please, remove this file, then, try another file that ends in .jpeg, .jpg, .png, .pdf, .bmp, .gif, .doc, .docx, .odt, .ods, or .odp."
          },
          {
            "key": "responseError",
            "string": "Sorry, there was an error on our end. Please, remove this file and try again. If the error continues please try again later."
          }
        ]
      }
    ]
  }
}

Guidance

The form card contains three major sections or slots that can be customized with additional content or components described below.

Header. This is the first section of the card that contains the following elements.

  • Heading. The overall question of the card that the form fields relate to.
  • Help message. Additional text that explains the question heading in further detail.
  • Alert. Including additional text in an alert helps emphasize the importance of the information being asked for in the card or provides the applicant with time-sensitive information.

Content. This is the main body of the form card that may contain any of the following types of content.

  • Process expectations. Expectations can be set for how long it takes an application to complete, the major steps of the application, or breakdowns of service offerings.
  • Form element components. Any form group component includes text inputs, text areas, selects, checkboxes, or radios.
  • Detailed examples. These may be sample answers, illustrations for hard-to-find information, or alternatives.
  • Informational summaries. These may include next-step summaries that set clear expectations for application submission follow-up.

Footer. This is the last section of the card that may contain any of the following elements in this order.

  1. Continue button. This primary element allows a user to submit the information asked for in a form card or progress to the next form card.
  2. Skip button. This gives the applicant time and flexibility in providing the information asked for in the form card.
  3. Yes or no buttons. Form cards with yes or no questions prevent applicants from answering irrelevant questions.
  4. Subtle link. This type of link enables applicants to take alternative actions with their applications that are allowed but discouraged.
  5. Subtle text. This type of text is used to reassure applicants to build trust, whether it's a note to remind them that we are securely protecting their personal information or a small alert to inform them that information has been sent to them.

Form groups vs. Fieldsets. The header and content sections may use a fieldset with a legend element for the heading when the form card contains form element components.

  • Form cards, with a combination of text inputs, text areas, selects, and checkbox group or radio group, will use the form group markup.
  • All other form cards may use the fieldset and legend markup.
    • Form cards with single text input, text area, select, checkbox group or radio group.
    • Form cards with multiple text inputs, text areas, or selects will use the fieldset markup.

Refer to additional guidance on the USWDS documentation site.

USWDS documentation site

Additional references

Accessibility

  • Unchecked
    Customization to the visual appearance of the Form card has been verified for WCAG 2.1 AA contrast minimum success.
  • Unchecked
    The Form card examples pass manual audits (WCAG 2.1 AA using axe or Lighthouse).
  • Unchecked
    The Form card achieves WCAG 2.1 AA resizing success.
    Resizing text up to 200% without loss of content or functionality.
  • Unchecked
    The Form card passes keyboard interaction tests.
    No keyboard test has been created.
  • Unchecked
    The Form card passes screen reader interaction tests.

  • Unchecked
    Guidance on ensuring Form card accessibility has been provided in this documentation.

Checklist Key

  • Passes
    Passes
  • Unchecked
    Unchecked

Design library component

Source and usage

Package: @codeforamerica/uswds/packages/cfa-form-card

  • Sass stylesheet: ./_cfa-form-card.scss
  • Thymeleaf template fragment: ./cfa-form-card.th.html
  • Embedded Ruby (ERB) partial template: ./_cfa-form-card.html.erb
Packages are collections of functionality that make up a component. Typically, they include stylesheets, templates, and scripts. Learn more about packages on the USWDS documentation site.
Sass theme settings

Below is a demonstration of customizing the component theme settings. Refer to the theme and package-level settings documentation.

// Theme-level settings
@use 'uswds-core' with (
  // The Form card uses settings from the USWDS Card component
  $theme-card-border-width: 2px
  $theme-card-border-color: 'base-lighter'
  $theme-card-border-radius: 'lg'
);
// Package-level settings
@use 'cfa-core' with (
  $cfa-form-card-header-typeset: 'heading', 'xl', 2
);
Thymeleaf template fragment

This is the pre-rendered template fragment from the package. It is the same template used to render the demonstrations above. You may copy and paste from this example or use the template using the th:block th:replace tag. See the example below.

<main th:fragment="formCard(modifier, id, ariaLabel, form, graphic, fieldset, header, content, formGroups, footer)" class="cfa-form-card" th:classappend="${modifier}" th:attr="id=${id},aria-label=${ariaLabel}">
  <form class="usa-form" th:classappend="${form.modifier}" th:attr="name=${form.name},rel=${form.rel},method=${form.method},action=${form.action},autocomplete=${form.autocomplete},enctype=${form.enctype},novalidate=${form.novalidate},target=${form.target}">
    <svg th:if="${graphic}" class="cfa-form-card__graphic usa-icon" aria-hidden="true" focusable="false" role="img">
      <use th:href="${graphic}"></use>
    </svg>
    <fieldset th:if="${fieldset}" class="usa-fieldset cfa-fieldset">
      <legend th:if="${header.heading.text}" class="cfa-form-card__heading">
        <h1 th:attr="id=${header.heading.id}" th:text="${header.heading.text}">Heading</h1>
      </legend>
      <legend th:if="${header.heading.content}" class="cfa-form-card__heading" th:utext="${header.heading.content}">
        <h1>Heading</h1>
      </legend>
      <div th:if="${header.helpMessage.text}" class="cfa-form-card__help-message">
        <p th:text="${header.helpMessage.text}">Help message.</p>
      </div>
      <div th:if="${header.helpMessage.content}" class="cfa-form-card__help-message" th:utext="${header.helpMessage.content}">
        <p>Help message.</p>
      </div>
      <div th:if="${header.details}" class="cfa-form-card__details">
        <div th:each="details: ${header.details}">
          <th:block th:replace="~{packages/cfa-details/cfa-details.th :: details(${details.modifier}, ${details.summary}, ${details.controls}, ${details.openAttr}, ${details.icon}, ${details.body}, ${details.text})}"></th:block>
        </div>
      </div>
      <div th:if="${header.alert}">
        <th:block th:replace="~{packages/cfa-alert/cfa-alert.th :: alert(${header.alert.modifier}, ${header.alert.role}, ${header.alert.label}, ${header.alert.labelledby}, ${header.alert.heading}, ${header.alert.body}, ${header.alert.text})}"></th:block>
      </div>
      <div class="cfa-form-card__content">
        <div th:each="formGroup: ${fieldset.formGroups}">
          <div th:if="${formGroup.input}">
            <div th:if="${formGroup.inputGroup}">
              <th:block th:replace="~{packages/cfa-form-group/cfa-form-group.th :: formGroup(${formGroup.modifier}, ${formGroup.id}, ${formGroup.label}, ${formGroup.input}, '', '', ${formGroup.hint}, ${formGroup.error}, ${formGroup.inputGroup})}" />
            </div>
            <div th:unless="${formGroup.inputGroup}">
              <th:block th:replace="~{packages/cfa-form-group/cfa-form-group.th :: formGroup(${formGroup.modifier}, ${formGroup.id}, ${formGroup.label}, ${formGroup.input}, '', '', ${formGroup.hint}, ${formGroup.error}, '')}" />
            </div>
          </div>
          <div th:if="${formGroup.textarea}">
            <th:block th:replace="~{packages/cfa-form-group/cfa-form-group.th :: formGroup(${formGroup.modifier}, ${formGroup.id}, ${formGroup.label}, '', '', ${formGroup.textarea}, ${formGroup.hint}, ${formGroup.error}, '')}" />
          </div>
          <div th:if="${formGroup.selectEl}">
            <th:block th:replace="~{packages/cfa-form-group/cfa-form-group.th :: formGroup(${formGroup.modifier}, ${formGroup.id}, ${formGroup.label}, '', '', '', ${formGroup.hint}, ${formGroup.error}, ${formGroup.selectEl})}" />
          </div>
          <div th:if="${formGroup.options}" class="cfa-form-card__input-select-group">
            <th:block th:replace="~{packages/cfa-input-select/cfa-input-select.th :: inputSelect(${formGroup.options}, ${formGroup.required})}" />
          </div>
          <div th:if="${formGroup.fileInput}">
            <th:block th:replace="~{packages/cfa-file-selector/cfa-file-selector.th :: fileSelector(${formGroup.id}, ${formGroup.fileInput}, ${formGroup.previewHeader}, ${formGroup.previewTemplate}, ${formGroup.defaultPreviewTemplate}, ${formGroup.dict})}" />
          </div>
        </div>
      </div>
    </fieldset>
    <div th:unless="${fieldset}">
      <div th:if="${header.heading.text}" class="cfa-form-card__heading">
        <h1 th:attr="id=${header.heading.id}" th:text="${header.heading.text}">Heading</h1>
      </div>
      <div th:if="${header.heading.content}" class="cfa-form-card__heading" th:utext="${header.heading.content}">
        <h1>Heading</h1>
      </div>
      <div th:if="${header.helpMessage.text}" class="cfa-form-card__help-message">
        <p th:text="${header.helpMessage.text}">Help message.</p>
      </div>
      <div th:if="${header.helpMessage.content}" class="cfa-form-card__help-message" th:utext="${header.helpMessage.content}">
        <p>Help message.</p>
      </div>
      <div th:if="${header.details}" class="cfa-form-card__details">
        <div th:each="details: ${header.details}">
          <th:block th:replace="~{packages/cfa-details/cfa-details.th :: details(${details.modifier}, ${details.summary}, ${details.controls}, ${details.openAttr}, ${details.icon}, ${details.body}, ${details.text})}"></th:block>
        </div>
      </div>
      <div th:if="${header.alert}">
        <th:block th:replace="~{packages/cfa-alert/cfa-alert.th :: alert(${header.alert.modifier}, ${header.alert.role}, ${header.alert.label}, ${header.alert.labelledby}, ${header.alert.heading}, ${header.alert.body}, ${header.alert.text})}"></th:block>
      </div>
      <div th:if="${content}" class="cfa-form-card__content" th:utext="${content}">
        <p>Content</p>
      </div>
      <div th:if="${formGroups}" class="cfa-form-card__content">
        <div th:each="formGroup: ${formGroups}">
          <div th:if="${formGroup.input}">
            <div th:if="${formGroup.inputGroup}">
              <th:block th:replace="~{packages/cfa-form-group/cfa-form-group.th :: formGroup(${formGroup.modifier}, ${formGroup.id}, ${formGroup.label}, ${formGroup.input}, '', '', ${formGroup.hint}, ${formGroup.error}, ${formGroup.inputGroup})}" />
            </div>
            <div th:unless="${formGroup.inputGroup}">
              <th:block th:replace="~{packages/cfa-form-group/cfa-form-group.th :: formGroup(${formGroup.modifier}, ${formGroup.id}, ${formGroup.label}, ${formGroup.input}, '', '', ${formGroup.hint}, ${formGroup.error}, '')}" />
            </div>
          </div>
          <div th:if="${formGroup.textarea}">
            <th:block th:replace="~{packages/cfa-form-group/cfa-form-group.th :: formGroup(${formGroup.modifier}, ${formGroup.id}, ${formGroup.label}, '', '', ${formGroup.textarea}, ${formGroup.hint}, ${formGroup.error}, '')}" />
          </div>
          <div th:if="${formGroup.selectEl}">
            <th:block th:replace="~{packages/cfa-form-group/cfa-form-group.th :: formGroup(${formGroup.modifier}, ${formGroup.id}, ${formGroup.label}, '', '', '', ${formGroup.hint}, ${formGroup.error}, ${formGroup.selectEl})}" />
          </div>
          <div th:if="${formGroup.memorableDate}">
            <th:block th:replace="~{packages/cfa-memorable-date/cfa-memorable-date.th :: memorableDate(${formGroup.fieldset}, ${formGroup.id}, ${formGroup.modifier}, ${formGroup.month}, ${formGroup.day}, ${formGroup.year})}" />
          </div>
          <div th:if="${formGroup.options}" class="cfa-form-card__input-select-group">
            <th:block th:replace="~{packages/cfa-fieldset/cfa-fieldset.th :: fieldset(${formGroup.modifier}, ${formGroup.id}, ${formGroup.legend}, ${formGroup.required}, ${formGroup.hint}, ${formGroup.error}, ${formGroup.options})}" />
          </div>
          <div th:if="${formGroup.fileInput}">
            <th:block th:replace="~{packages/cfa-file-selector/cfa-file-selector.th :: fileSelector(${formGroup.id}, ${formGroup.fileInput}, ${formGroup.previewHeader}, ${formGroup.previewTemplate}, ${formGroup.defaultPreviewTemplate}, ${formGroup.dict})}" />
          </div>
        </div>
      </div>
    </div>
    <div th:if="${footer}" class="cfa-form-card__footer">
      <div th:if="${footer.submit}">
        <th:block th:replace="~{packages/cfa-button/cfa-button.th :: button(${footer.submit})}" />
      </div>
      <div th:if="${footer.skip}">
        <th:block th:replace="~{packages/cfa-button/cfa-button.th :: button(${footer.skip})}" />
      </div>
      <div th:if="${footer.group}">
        <th:block th:replace="~{packages/cfa-button/cfa-button.th :: button(${footer.group})}" />
      </div>
      <div th:if="${footer.subtleText}" th:utext="${footer.subtleText}">
        <p>Subltle text.</p>
      </div>
    </div>
  </form>
</main>
Template fragment inclusion

Below is an example of how to use the fragment from the package directory using the th:block th:replace inclusion tag. Replace the fragment parameters using your variables or context.

<th:block th:replace="~{packages/cfa-form-card/cfa-form-card.th :: formCard(${modifier}, ${id}, ${ariaLabel}, ${form}, ${graphic}, ${fieldset}, ${header}, ${content}, ${formGroups}, ${footer})}" />
ERB template partial

This is the pre-rendered partial template from the package. You may copy and paste from this example or use the template directly from the path.

<main class="cfa-form-card<% if defined?(modifier) %> <%= modifier %><% end %>"
  <% if defined?(id) %> id="<%= id %>"<% end %>
  <% if defined?(ariaLabel) %> aria-label="<%= ariaLabel %>"<% end %>>
  <form class="usa-form<% if defined?(form) && form['modifier'] %> <%= form['modifier'] %><% end %>"
    <% if defined?(form) && form['name'] %> name="<%= form['name'] %><% end %>
    <% if defined?(form) && form['rel'] %> rel="<%= form['rel'] %><% end %>
    <% if defined?(form) && form['method'] %> method="<%= form['method'] %><% end %>
    <% if defined?(form) && form['action'] %> action="<%= form['action'] %><% end %>
    <% if defined?(form) && form['autocomplete'] %> autocomplete="<%= form['autocomplete'] %><% end %>
    <% if defined?(form) && form['enctype'] %> enctype="<%= form['enctype'] %><% end %>
    <% if defined?(form) && form['novalidate'] %> novalidate="<%= form['novalidate'] %><% end %>
    <% if defined?(form) && form['target'] %> target="<%= form['target'] %><% end %>>
    <% if defined?(graphic) %><svg class="cfa-form-card__graphic usa-icon" aria-hidden="true" focusable="false" role="img">
      <use href="<%= graphic %>"></use>
    </svg><% end %>
    <% if defined?(fieldset) %><fieldset class="usa-fieldset<% if fieldset['modifier'] %> <%= fieldset['modifier'] %><% end %>">
      <% if header.has_key?('heading') && header['heading']['text'] %><legend class="cfa-form-card__heading">
        <h1 <% if header['heading']['id'] %> id="<%= header['heading']['id'] %>"<% end %>><%= header['heading']['text'] %></h1>
      </legend><% end %>
      <% if header.has_key?('heading') && header['heading']['content'] %><legend class="cfa-form-card__heading">
        <%= header['heading']['content'] %>
      </legend><% end %>
      <% if header.has_key?('helpMessage') && header['helpMessage']['text'] %><div class="cfa-form-card__help-message">
        <p><%= header['helpMessage']['text'] %></p>
      </div><% end %>
      <% if header.has_key?('helpMessage') && header['helpMessage']['content'] %><div class="cfa-form-card__help-message">
        <%= header['helpMessage']['content'] %>
      </div><% end %>
      <% if header.has_key?('details') %><div class="cfa-form-card__details">
        <% header['details'].each do |details| %><div>
        <%= ERB.new(File.read('packages/cfa-details/_cfa-details.html.erb'), 0, 0, [*('a'..'z')].sample(8).join)
          .result_with_hash({
            modifier: (details['modifier'] if details['modifier']),
            summary: (details['summary'] if details['summary']),
            controls: (details['controls'] if details['controls']),
            openAttr: (details['openAttr'] if details['openAttr']),
            icon: (details['icon'] if details['icon']),
            body: (details['body'] if details['body']),
            text: (details['text'] if details['text'])
          }.compact) %>
        </div><% end %>
      </div><% end %>
      <% if header['alert'] %><div>
        <%= ERB.new(File.read('packages/cfa-alert/_cfa-alert.html.erb'), 0, 0, '@alert')
          .result_with_hash({
            modifier: (header['alert']['modifier'] if header['alert']['modifier']),
            role: (header['alert']['role'] if header['alert']['role']),
            heading: (header['alert']['heading'] if header['alert']['heading']),
            label: (header['alert']['label'] if header['alert']['label']),
            labelledby: (header['alert']['labelledby'] if header['alert']['labelledby']),
            body: (header['alert']['body'] if header['alert']['body']),
            text: (header['alert']['text'] if header['alert']['text'])
          }.compact) %>
      </div><% end %>
      <div class="cfa-form-card__content">
        <% fieldset['formGroups'].each do |formGroup| %><div>
          <% if formGroup['input'] %>
          <%= ERB.new(File.read('packages/cfa-form-group/_cfa-form-group.html.erb'), 0, 0, [*('a'..'z')].sample(8).join)
            .result_with_hash({
              modifier: (formGroup['modifier'] if formGroup['modifier']),
              id: (formGroup['id'] if formGroup['id']),
              label: (formGroup['label'] if formGroup['label']),
              hint: (formGroup['hint'] if formGroup['hint']),
              error: (formGroup['error'] if formGroup['error']),
              input: formGroup['input'],
              inputGroup: (formGroup['inputGroup'] if formGroup['inputGroup'])
            }.compact) %>
          <% end %>
          <% if formGroup['textarea'] %>
          <%= ERB.new(File.read('packages/cfa-form-group/_cfa-form-group.html.erb'), 0, 0, [*('a'..'z')].sample(8).join)
            .result_with_hash({
              modifier: (formGroup['modifier'] if formGroup['modifier']),
              id: (formGroup['id'] if formGroup['id']),
              label: (formGroup['label'] if formGroup['label']),
              hint: (formGroup['hint'] if formGroup['hint']),
              error: (formGroup['error'] if formGroup['error']),
              textarea: formGroup['textarea']
            }.compact) %>
          <% end %>
          <% if formGroup['selectEl'] %>
          <%= ERB.new(File.read('packages/cfa-form-group/_cfa-form-group.html.erb'), 0, 0, [*('a'..'z')].sample(8).join)
            .result_with_hash({
              modifier: (formGroup['modifier'] if formGroup['modifier']),
              id: (formGroup['id'] if formGroup['id']),
              label: (formGroup['label'] if formGroup['label']),
              hint: (formGroup['hint'] if formGroup['hint']),
              error: (formGroup['error'] if formGroup['error']),
              selectEl: formGroup['selectEl']
            }.compact) %>
          <% end %>
          <% if formGroup['options'] %><div class="cfa-form-card__input-select-group">
            <%= ERB.new(File.read('packages/cfa-input-select/_cfa-input-select.html.erb'), 0, 0, [*('a'..'z')].sample(8).join)
              .result_with_hash({
                options: (formGroup['options'] if formGroup['options']),
                required: (formGroup['required'] if formGroup['required'])
              }.compact) %>
          </div><% end %>
          <% if formGroup['fileInput'] %>
          <%= ERB.new(File.read('packages/cfa-file-selector/_cfa-file-selector.html.erb'), 0, 0, [*('a'..'z')].sample(8).join)
            .result_with_hash({
              id: (formGroup['id'] if formGroup['id']),
              fileInput: formGroup['fileInput'],
              previewHeader: (formGroup['previewHeader'] if formGroup['previewHeader']),
              previewTemplate: (formGroup['previewTemplate'] if formGroup['previewTemplate']),
              defaultPreviewTemplate: (formGroup['defaultPreviewTemplate'] if formGroup['defaultPreviewTemplate']),
              dict: (formGroup['dict'] if formGroup['dict'])
            }.compact) %>
          <% end %>
        </div><% end %>
      </div>
    </fieldset>
    <% else %>
    <div>
      <% if header.has_key?('heading') && header['heading']['text'] %><div class="cfa-form-card__heading">
        <h1 <% if header['heading']['id'] %> id="<%= header['heading']['id'] %>"<% end %>><%= header['heading']['text'] %></h1>
      </div><% end %>
      <% if header.has_key?('heading') && header['heading']['content'] %><div class="cfa-form-card__heading">
        <%= header['heading']['content'] %>
      </div><% end %>
      <% if header.has_key?('helpMessage') && header['helpMessage']['text'] %><div class="cfa-form-card__help-message">
        <p><%= header['helpMessage']['text'] %></p>
      </div><% end %>
      <% if header.has_key?('helpMessage') && header['helpMessage']['content'] %><div class="cfa-form-card__help-message">
        <%= header['helpMessage']['content'] %>
      </div><% end %>
      <% if header.has_key?('details') %><div class="cfa-form-card__details">
        <% header['details'].each do |details| %><div>
        <%= ERB.new(File.read('packages/cfa-details/_cfa-details.html.erb'), 0, 0, [*('a'..'z')].sample(8).join)
          .result_with_hash({
            modifier: (details['modifier'] if details['modifier']),
            summary: (details['summary'] if details['summary']),
            controls: (details['controls'] if details['controls']),
            openAttr: (details['openAttr'] if details['openAttr']),
            icon: (details['icon'] if details['icon']),
            body: (details['body'] if details['body']),
            text: (details['text'] if details['text'])
          }.compact) %>
        </div><% end %>
      </div><% end %>
      <% if header['alert'] %><div>
        <%= ERB.new(File.read('packages/cfa-alert/_cfa-alert.html.erb'), 0, 0, '@alert')
          .result_with_hash({
            modifier: (header['alert']['modifier'] if header['alert']['modifier']),
            role: (header['alert']['role'] if header['alert']['role']),
            heading: (header['alert']['heading'] if header['alert']['heading']),
            label: (header['alert']['label'] if header['alert']['label']),
            labelledby: (header['alert']['labelledby'] if header['alert']['labelledby']),
            body: (header['alert']['body'] if header['alert']['body']),
            text: (header['alert']['text'] if header['alert']['text'])
          }.compact) %>
      </div><% end %>
      <% if defined?(content) %><div class="cfa-form-card__content">
        <%= content %>
      </div><% end %>
      <% if defined?(formGroups) %><div class="cfa-form-card__content">
        <% formGroups.each do |formGroup| %><div>
          <% if formGroup['input'] %>
          <%= ERB.new(File.read('packages/cfa-form-group/_cfa-form-group.html.erb'), 0, 0, [*('a'..'z')].sample(8).join)
            .result_with_hash({
              modifier: (formGroup['modifier'] if formGroup['modifier']),
              id: (formGroup['id'] if formGroup['id']),
              label: (formGroup['label'] if formGroup['label']),
              hint: (formGroup['hint'] if formGroup['hint']),
              error: (formGroup['error'] if formGroup['error']),
              input: formGroup['input'],
              inputGroup: (formGroup['inputGroup'] if formGroup['inputGroup'])
            }.compact) %>
          <% end %>
          <% if formGroup['textarea'] %>
          <%= ERB.new(File.read('packages/cfa-form-group/_cfa-form-group.html.erb'), 0, 0, [*('a'..'z')].sample(8).join)
            .result_with_hash({
              modifier: (formGroup['modifier'] if formGroup['modifier']),
              id: (formGroup['id'] if formGroup['id']),
              label: (formGroup['label'] if formGroup['label']),
              hint: (formGroup['hint'] if formGroup['hint']),
              error: (formGroup['error'] if formGroup['error']),
              textarea: formGroup['textarea']
            }.compact) %>
          <% end %>
          <% if formGroup['selectEl'] %>
          <%= ERB.new(File.read('packages/cfa-form-group/_cfa-form-group.html.erb'), 0, 0, [*('a'..'z')].sample(8).join)
            .result_with_hash({
              modifier: (formGroup['modifier'] if formGroup['modifier']),
              id: (formGroup['id'] if formGroup['id']),
              label: (formGroup['label'] if formGroup['label']),
              hint: (formGroup['hint'] if formGroup['hint']),
              error: (formGroup['error'] if formGroup['error']),
              selectEl: formGroup['selectEl']
            }.compact) %>
          <% end %>
          <% if formGroup['memorableDate'] %>
          <%= ERB.new(File.read('packages/cfa-memorable-date/_cfa-memorable-date.html.erb'), 0, 0, [*('a'..'z')].sample(8).join)
            .result_with_hash({
              modifier: (formGroup['modifier'] if formGroup['modifier']),
              id: (formGroup['id'] if formGroup['id']),
              fieldset: (formGroup['fieldset'] if formGroup['fieldset']),
              month: (formGroup['month'] if formGroup['month']),
              day: (formGroup['day'] if formGroup['day']),
              year: (formGroup['year'] if formGroup['year'])
            }.compact) %>
          <% end %>
          <% if formGroup['options'] %><div class="cfa-form-card__input-select-group">
          <%= ERB.new(File.read('packages/cfa-fieldset/_cfa-fieldset.html.erb'), 0, 0, [*('a'..'z')].sample(8).join)
            .result_with_hash({
              modifier: (formGroup['modifier'] if formGroup['modifier']),
              id: (formGroup['id'] if formGroup['id']),
              legend: (formGroup['legend'] if formGroup['legend']),
              hint: (formGroup['hint'] if formGroup['hint']),
              required: (formGroup['required'] if formGroup['required']),
              error: (formGroup['error'] if formGroup['error']),
              options: (formGroup['options'] if formGroup['options'])
            }.compact) %>
          </div><% end %>
          <% if formGroup['fileInput'] %>
          <%= ERB.new(File.read('packages/cfa-file-selector/_cfa-file-selector.html.erb'), 0, 0, [*('a'..'z')].sample(8).join)
            .result_with_hash({
              id: (formGroup['id'] if formGroup['id']),
              fileInput: formGroup['fileInput'],
              previewHeader: (formGroup['previewHeader'] if formGroup['previewHeader']),
              previewTemplate: (formGroup['previewTemplate'] if formGroup['previewTemplate']),
              defaultPreviewTemplate: (formGroup['defaultPreviewTemplate'] if formGroup['defaultPreviewTemplate']),
              dict: (formGroup['dict'] if formGroup['dict'])
            }.compact) %>
          <% end %>
        </div><% end %>
      </div><% end %>
    </div>
    <% end %>
    <% if defined?(footer) %><div class="cfa-form-card__footer">
      <% if footer.has_key?('submit') %><div>
        <%= ERB.new(File.read('packages/cfa-button/_cfa-button.html.erb'), 0, 0, '@submit').result_with_hash({items: footer['submit']}) %>
      </div><% end %>
      <% if footer.has_key?('skip') %><div>
        <%= ERB.new(File.read('packages/cfa-button/_cfa-button.html.erb'), 0, 0, '@skip').result_with_hash({items: footer['skip']}) %>
      </div><% end %>
      <% if footer.has_key?('group') %><div>
        <%= ERB.new(File.read('packages/cfa-button/_cfa-button.html.erb'), 0, 0, '@group').result_with_hash({items: footer['group']}) %>
      </div><% end %>
      <% if footer.has_key?('subtleText') %><div>
        <%= footer['subtleText'] %>
      </div><% end %>
    </div><% end %>
  </form>
</main>
Partial render

Below is an example of how to include the partial in a view from the package directory using the Ruby ERB class. Replace the argument values using your variables or context. In a Rails environment, the render method can be used instead with the same hash values.

<%= ERB.new(File.read('packages/cfa-form-card/_cfa-form-card.html.erb'), 0, 0, '@formCard').result_with_hash({modifier: modifier, id: id, ariaLabel: ariaLabel, graphic: graphic, content: content, fieldset: fieldset, header: header, formGroups: formGroups, footer: footer}) %>

uswds.codeforamerica.org

Learn more about Code for America by visiting codeforamerica.org