text area

The <textarea> element can be used for multi-line input. It features an optional label and an optional placeholder as well as success, error and warning states.

The dynamic-height variant will adjust its height to match the content.

See Form for example usage in a form.

In order for the label to work correctly, the input tag needs a unique id attribute and the label tag needs the same for attribute.
According to the Web Content Accessibility Guidelines (WCAG), it is highly reccomended to use a label together with the text area.

This component works with all its features only in browsers that have support for the :has CSS selector. Please refer to the reference on MDN.
If you need to run this component in a browser with no support for the :has CSS selector, please use the FROK Release 3.6.x.

component variations

Standard text area

<div class="a-text-area"><textarea id="1"></textarea></div>

Standard text area disabled

<div class="a-text-area"><textarea id="2" disabled=""></textarea></div>

Standard text area label

<div class="a-text-area">
  <label for="3">Label</label>
  <textarea id="3"></textarea>
</div>

Standard text area label readonly

<div class="a-text-area">
  <label for="4">Label</label>
  <textarea id="4" readonly=""></textarea>
</div>

Standard text area label disabled

<div class="a-text-area">
  <label for="5">Label</label>
  <textarea id="5" disabled=""></textarea>
</div>

Standard text area very long label

<div class="a-text-area">
  <label for="6">
    Lorem ipsum dolor, sit amet consectetur adipisicing elit. Vitae omnis labore
    consequatur distinctio provident voluptatum nisi recusandae quod asperiores
    quo, architecto cum nesciunt nemo, vel minima possimus et blanditiis
    numquam, cupiditate deserunt fugit delectus earum ducimus alias! Quam atque
    laborum tempore alias magnam tenetur fuga facere totam, harum, ipsa sit!
  </label>
  <textarea id="6"></textarea>
</div>

Standard text area label and placeholder

<div class="a-text-area">
  <label for="7">Label</label>
  <textarea id="7" placeholder="Type something"></textarea>
</div>

Standard text area placeholder

<div class="a-text-area">
  <textarea id="8" placeholder="Type something"></textarea>
</div>

Standard text area dynamic Height

<div class="a-text-area a-text-area--dynamic-height">
  <textarea id="9"></textarea>
  <div class="a-text-area__shadow"></div>
</div>

Standard text area disabled dynamic Height

<div class="a-text-area a-text-area--dynamic-height">
  <textarea id="10" disabled=""></textarea>
  <div class="a-text-area__shadow"></div>
</div>

Standard text area placeholder dynamic Height

<div class="a-text-area a-text-area--dynamic-height">
  <textarea id="11" placeholder="Type something"></textarea>
  <div class="a-text-area__shadow"></div>
</div>

Disabled text area placeholder dynamic Height

<div class="a-text-area a-text-area--dynamic-height">
  <textarea id="12" disabled="" placeholder="Type something"></textarea>
  <div class="a-text-area__shadow"></div>
</div>

additional content

styles SCSS

.a-text-area {
  position: relative;
  height: 7.5rem;
  width: 100%;
  overflow: hidden;

  textarea[readonly],
  textarea:hover[readonly],
  textarea:active[readonly],
  textarea:focus[readonly],
  textarea:disabled[readonly] {
    background-color: var(--plain__enabled__fill__default);
    color: var(--plain__enabled__front__default);
    pointer-events: none;

    &::placeholder {
      color: var(--plain__enabled__front__default);
    }
  }

  textarea,
  &__shadow {
    color: var(--neutral__enabled__front__default);
    background-color: var(--neutral__enabled__fill__default);
    border: none;
    border-bottom: 0.0625rem solid var(--neutral__enabled__front__default);
    height: 7.5rem;
    min-height: 7.5rem;
    padding: 0.75rem 1rem;
    width: 100%;
    resize: none;
    line-height: 1.5;

    &::placeholder {
      color: var(--plain__enabled__front__default);
      opacity: 0.5;
    }

    &:hover {
      background-color: var(--neutral__enabled__fill__hovered);
      color: var(--neutral__enabled__front__hovered);
      cursor: text;
    }

    &:active {
      background-color: var(--neutral__enabled__fill__pressed);
      color: var(--neutral__enabled__front__pressed);
      cursor: text;
    }

    /* stylelint-disable-next-line a11y/no-outline-none */
    &:focus {
      background-color: var(--neutral__focused__fill__default);
      border-bottom-color: var(--neutral__focused__front__default);
      cursor: text;
    }

    &:focus-visible {
      border: 0.1875rem solid var(--plain__enabled__front__default);
      outline: 0.1875rem solid var(--background);
      outline-offset: -0.375rem;
      padding-inline: 0.8125rem;
      padding-block-start: 0.625rem;
    }

    &:disabled {
      border-bottom-color: var(--neutral__disabled__front__default);
      background-color: var(--neutral__disabled__fill__default);
      color: var(--neutral__disabled__front__default);
      pointer-events: none;

      &::placeholder {
        color: var(--neutral__disabled__front__default);
      }
    }
  }

  &__shadow {
    white-space: pre-wrap;
    height: auto;
    width: 100%;
    position: absolute;
    left: -9999px;
  }

  &--dynamic-height {
    height: 100%;
    // a grid is being used to make it possible that the text area's height would be dynamic,
    // with the data attribute on the after pseudo element
    vertical-align: top;
    align-items: center;
    grid-template-columns: 100% 100%;
  }

  label {
    position: absolute;
    margin: 0.25rem 1rem auto 1rem;
    font-size: 0.75rem;
    max-width: calc(100% - 2.25rem);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;

    &:has(~ textarea:disabled) {
      color: var(--neutral__disabled__front__default);
    }

    + textarea {
      border-top: 1.375rem solid transparent;
      padding-top: 0;

      &:focus-visible {
        padding-block-start: 1.1875rem;
      }
    }
  }
}