home/veldform/docs

Veldform / Docs

Customization

Veldform is built to be styled. All plugin CSS lives in a CSS layer (@layer veldform), which means any rule you write in your theme wins — no specificity wars, no !important.

Design tokens

The quickest way to restyle your forms is overriding the design tokens. They are scoped to .vf-form:

Token Default Controls
--vf-color-accent #2271b1 Buttons, focus rings, active step
--vf-color-error #d63638 Validation messages, required asterisk
--vf-color-border #8c8f94 Input and fieldset borders
--vf-color-text currentColor Form text
--vf-space 1rem Vertical rhythm and grid gap
--vf-field-radius 4px Input and button corner radius
--vf-control-pad 0.5rem 0.6rem Input padding
--vf-max-width 40rem Form max width

For example:

.vf-form {
    --vf-color-accent: var(--wp--preset--color--primary);
    --vf-field-radius: 0;
}

theme.json

If you're building a block theme, you can set the tokens from theme.json under settings.custom.veldform. The keys map to the token names without the --vf- prefix:

{
    "settings": {
        "custom": {
            "veldform": {
                "accent": "#0a4b78",
                "radius": "0px",
                "max-width": "48rem"
            }
        }
    }
}

Classes

The rendered markup uses one shallow class per element, and the class names are a stable API — safe to target from your theme. The main ones:

  • .vf-form — the form element
  • .vf-row — a row (12-column grid)
  • .vf-field and .vf-field--{type} — a field wrapper, e.g. .vf-field--email
  • .vf-label, .vf-required, .vf-help, .vf-field-error
  • .vf-input, .vf-textarea, .vf-select, .vf-file
  • .vf-group / .vf-legend — radio and checkbox fieldsets
  • .vf-submit, .vf-prev, .vf-next — buttons
  • .vf-errors — the error summary, .vf-success — the confirmation
  • .vf-steps — the progress indicator on multi-step forms

Every field wrapper also carries data-vf-field="f_yourfield", so you can target one specific field:

.vf-form [data-vf-field="f_message"] .vf-textarea {
    min-height: 200px;
}

Template overriding

If CSS isn't enough, your theme can take over the markup of any field type. Veldform looks for templates in your (child) theme:

your-theme/
└── veldform/
    └── fields/
        ├── text.php      <- overrides the text control
        ├── select.php    <- overrides selects
        └── default.php   <- fallback for every other type

The override replaces the control element only — the wrapper, label, help text and error message still come from the plugin, so accessibility keeps working. Inside the template you have $field (the field settings), $value and $ctx. Make sure you keep using $ctx['id'] and $ctx['name']:

<input type="text"
    id="<?php echo esc_attr( $ctx['id'] ); ?>"
    name="<?php echo esc_attr( $ctx['name'] ); ?>"
    class="my-input"
    value="<?php echo esc_attr( $value ); ?>"
    <?php echo $ctx['required'] ? 'required' : ''; ?> />

Markup filters

For surgical changes without copying a template, there are three filters: veldform/render/control (the bare control), veldform/render/field (the complete field block) and veldform/form/wrapper (the whole form). See Action and filter hooks.

Disabling the plugin CSS

Want to style everything yourself, from scratch? Stop the stylesheet from loading:

add_filter( 'veldform/render/styles', '__return_false' );

The filter also receives the form ID, so you can disable it for specific forms only.

Email template

Notification emails are wrapped in a minimal HTML template (logo, body, footer). You can:

  • Turn it off globally under Veldform -> Settings
  • Override it from your theme with your-theme/veldform/email.php (receives $content, $logo, $footer and $context)
  • Adjust parts of it with the veldform/email/logo, veldform/email/footer and veldform/email/html filters