25% off ProSNIPC25OFF

Contact Form 7: Floating-Label Styled Form

Transforms Contact Form 7 forms with floating label animations and focus ring styles, with a PHP body-class guard.

Module3 parts · by SnipCraft

PHPBody Class Guard

php
<?php
if ( ! defined( 'WPCF7_VERSION' ) ) {
    return;
}

if ( ! function_exists( 'scseed_cf7_body_class' ) ) {
    function scseed_cf7_body_class( $classes ) {
        $classes[] = 'scseed-cf7-fl';
        return $classes;
    }
    add_filter( 'body_class', 'scseed_cf7_body_class' );
}

CSSStyles

css
/* Scoped to body.scseed-cf7-fl so styles only apply when CF7 is active */
.scseed-cf7-fl .wpcf7-form span.wpcf7-form-control-wrap {
    position: relative;
    display: block;
    margin-top: 4px;
}
.scseed-cf7-fl .wpcf7-form input[type="text"],
.scseed-cf7-fl .wpcf7-form input[type="email"],
.scseed-cf7-fl .wpcf7-form input[type="tel"],
.scseed-cf7-fl .wpcf7-form input[type="url"],
.scseed-cf7-fl .wpcf7-form input[type="number"],
.scseed-cf7-fl .wpcf7-form textarea {
    width: 100%;
    border: 1px solid #ccc;
    border-radius: 4px;
    padding: 20px 12px 6px;
    font-size: 1em;
    background: #fff;
    transition: border-color .2s, box-shadow .2s;
    box-sizing: border-box;
}
.scseed-cf7-fl .wpcf7-form input:focus,
.scseed-cf7-fl .wpcf7-form textarea:focus {
    outline: none;
    border-color: #7c5cff;
    box-shadow: 0 0 0 3px rgba(124,92,255,.15);
}
/* Floating label element added by JS */
.scseed-cf7-fl .wpcf7-form .scseed-float-lbl {
    position: absolute;
    top: 13px;
    left: 13px;
    font-size: 1em;
    color: #888;
    pointer-events: none;
    transition: top .18s ease, font-size .18s ease, color .18s ease;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: calc(100% - 26px);
}
.scseed-cf7-fl .wpcf7-form .scseed-float-lbl.is-up {
    top: 4px;
    font-size: .72em;
    color: #7c5cff;
}
.scseed-cf7-fl .wpcf7-form input[type="submit"] {
    background: #7c5cff;
    color: #fff;
    border: none;
    border-radius: 4px;
    padding: 10px 28px;
    font-size: 1em;
    cursor: pointer;
    transition: background .2s;
}
.scseed-cf7-fl .wpcf7-form input[type="submit"]:hover {
    background: #6243e8;
}

JavaScriptScript

js
(function () {
    if (!document.body.classList.contains('scseed-cf7-fl')) { return; }

    function wire(field, labelText) {
        var wrap = field.parentNode;
        var lbl  = document.createElement('span');
        lbl.className   = 'scseed-float-lbl';
        lbl.textContent = labelText;
        wrap.appendChild(lbl);

        function refresh() {
            if (field.value || document.activeElement === field) {
                lbl.classList.add('is-up');
            } else {
                lbl.classList.remove('is-up');
            }
        }

        field.addEventListener('focus', refresh);
        field.addEventListener('blur',  refresh);
        field.addEventListener('input', refresh);
        refresh();
    }

    function setupForm(form) {
        var fields = form.querySelectorAll(
            'input[type="text"], input[type="email"], input[type="tel"], input[type="url"], input[type="number"], textarea'
        );
        for (var i = 0; i < fields.length; i++) {
            var field = fields[i];
            // Try to find a label associated via <label> before the wrap
            var wrap  = field.parentNode;
            var para  = wrap.parentNode;
            var label = para ? para.querySelector('label') : null;
            var text  = label ? label.textContent.trim().replace(/s**$/, '') : field.getAttribute('placeholder') || '';
            if (!text) { continue; }
            // Remove placeholder to avoid duplication
            field.removeAttribute('placeholder');
            wire(field, text);
        }
    }

    document.addEventListener('DOMContentLoaded', function () {
        var forms = document.querySelectorAll('.wpcf7-form');
        for (var i = 0; i < forms.length; i++) {
            setupForm(forms[i]);
        }
    });
}());
#ux#forms#contact-form-7#cf7#floating-label