Add custom CSS class to an element

Learn how to add classes to any element.

Each component in Vueform has named DOMs. This means that we can target any part of any component with class modifiers, enabling us to add, remove, replace or override any of the component's CSS classes.

template
<Vueform>
  <!-- Add class to TextElement's container -->
  <TextElement add-class="custom-text-container">

  <!-- Add class to different parts of TextElement -->
  <TextElement :add-class="{
    container: 'custom-text-container',
    inputContainer: 'custom-text-input-container',
    input: 'custom-text-input',
  }">

  <!-- Add class to different parts of TextElement and its child components -->
  <TextElement :add-classes="{
    TextElement: {
      container: 'custom-text-container',
      inputContainer: 'custom-text-input-container',
      input: 'custom-text-input',
    },
    ElementLabel: {
      container: 'custom-text-label-container',
      wrapper: 'custom-text-label-wrapper',
    }
  }">
</Vueform>

Here's how for example TextElement's DOM structure looks like:

html
<div class="ElementLayout.container TextElement.container">
  <div class="ElementLayout.outerWrapper">
    <label class="ElementLabel.container">
      <span class="ElementLabel.wrapper">label</span>
      <span class="ElementInfo.container">
        <div class="ElementInfo.wrapper">
          <span class="ElementInfo.content">info</span>
        </div>
      </span>
    </label>
    <div class="ElementLayout.innerContainer">
      <div class="ElementLayout.innerWrapperBefore">
        <div class="ElementText.container_before">before</div>
      </div>
      <div class="ElementLayout.innerWrapper">
        <div
          class="TextElement.inputContainer">
          <div class="ElementAddon.container_before">
            <div class="ElementAddon.wrapper">$</div>
          </div>
          <div class="ElementAddon.container_after">
            <div class="ElementAddon.wrapper">%</div>
          </div>
          <input class="TextElement.input" />
        </div>
      </div>
      <div class="ElementLayout.innerWrapperAfter">
        <div class="ElementText.container_between">between</div>
        <div class="ElementDescription.container">description</div>
        <div class="ElementError.container">error</div>
        <div class="ElementText.container_after">after</div>
      </div>
    </div>
  </div>
</div>

The highlighted ones are the ones that are targeted with our :add-classes example above.

If we enable classHelpers, in vueform.config.js, Vueform will insert helper classnames to the DOM structure, letting us know about how DOM parts can be referenced in class modifiers.

js
// vueform.config.js

import { defineConfig } from '@vueform/vueform'

export default defineConfig({
  classHelpers: true,
})

Here's how our DOM structure in eg. Chrome's debug console would look like when classHelpers is turned on (DOM names are referenced in ComponentName.className--> format):

html
<div class="ElementLayout.container--> ElementLayout.container_md--> form-text col-span-12 TextElement.container--> form-text-type ElementLayout.container_error--> has-error">
  <div class="ElementLayout.outerWrapper--> grid grid-cols-12">
    <label class="ElementLabel.container--> flex items-start ElementLabel.container_md--> form-text col-span-12 ElementLabel.container_vertical_md--> form-pb-gutter/3 form-pt-0 form-pr-0" for="a" id="a__label">
      <span class="ElementLabel.wrapper-->">
        label
      </span>
      <span class="ElementInfo.container--> inline-block w-3.5 h-3.5 form-bg-info relative ml-1 cursor-pointer form-info-group">
        <div class="ElementInfo.wrapper--> absolute z-1000 -mt-px opacity-0 invisible info-group-hover:opacity-100 info-group-hover:form-visible transition-opacity w-52 flex ElementInfo.wrapper_right--> left-5 -top-0.5 justify-start" id="a__info">
          <span class="ElementInfo.content--> bg-black bg-opacity-90 text-white rounded-md form-text-small py-1 px-2.5 not-italic inline-block relative">
            info
          </span>
        </div>
      </span>
    </label>
    <div class="ElementLayout.innerContainer--> flex-1 grid grid-cols-12 col-span-12">
      <div class="ElementLayout.innerWrapperBefore--> col-span-12">
        <div class="ElementText.container--> ElementText.container_before-->">
          before
        </div>
      </div>
      <div class="ElementLayout.innerWrapper--> col-span-12">
        <div class="TextElement.inputContainer--> w-full flex flex-1 transition-input duration-200 border-solid form-border-width-input form-shadow-input form-input-group group TextElement.inputContainer_md--> form-radius-input form-h-input-height TextElement.inputContainer_danger--> form-bg-input-danger form-color-input-danger form-border-color-input-danger hover:form-shadow-input-hover focused:form-shadow-input-focus focused:form-ring focused-hover:form-shadow-input-hover">
          <div class="ElementAddon.container--> form-bg-addon form-color-addon flex items-center justify-center flex-grow-0 flex-shrink-0 ElementAddon.container_md--> ElementAddon.container_before--> ElementAddon.container_before_md--> form-radius-input-l form-pl-input form-pr-space-addon">
            <div class="ElementAddon.wrapper--> contents items-center justify-center">
              before-addon
            </div>
          </div>
          <div class="ElementAddon.container--> form-bg-addon form-color-addon flex items-center justify-center flex-grow-0 flex-shrink-0 ElementAddon.container_md--> ElementAddon.container_after--> order-2 ElementAddon.container_after_md--> form-radius-input-r form-pr-input form-pl-space-addon">
            <div class="ElementAddon.wrapper--> contents items-center justify-center">
              after-addon
            </div>
          </div>
          <input class="TextElement.input--> w-full bg-transparent h-full TextElement.input_md--> form-p-input form-radius-input form-text with-floating:form-p-input-floating TextElement.input_danger--> form-color-input-danger form-autofill-danger" type="text" name="a" id="a" aria-labelledby="a__label" aria-describedby="a__description a__info" aria-invalid="true" aria-errormessage="a__error" aria-disabled="false" aria-busy="false">
        </div>
      </div>
      <div class="ElementLayout.innerWrapperAfter--> col-span-12">
        <div class="ElementText.container--> ElementText.container_between-->">
          between
        </div>
        <div class="ElementDescription.container--> form-color-muted ElementDescription.container_md--> form-text-small mt-1" id="a__description">
          description
        </div>
        <div class="ElementError.container--> form-color-danger block ElementError.container_md--> form-text-small mt-1" id="a__error" aria-live="assertive">
          error
        </div>
        <div class="ElementText.container--> ElementText.container_after-->">
          after
        </div>
      </div>
    </div>
  </div>
</div>
  
👋 Hire Vueform team for form customizations and developmentLearn more