← Назад к шаблонам На главную
Авторизация

Авторизация с живой проверкой

Форма входа и регистрации для сайтов с личным кабинетом. Интерактивные подсказки помогают пользователю сразу видеть статус email, пароля и готовности формы.

Сложность: Сложная HTML CSS JavaScript form validation password strength UI animation tabs
ACCESS AUTH user session
JWT Password 2FA

Введите email и пароль — интерфейс покажет состояние формы.

Проверьте email и надёжность пароля перед созданием аккаунта.

<section class="auth-orbit">
    <div class="auth-orbit__visual">
        <div class="auth-orbit__core">
            <span>ACCESS</span>
            <strong>AUTH</strong>
            <small>user session</small>
        </div>

        <span class="auth-orbit__ring auth-orbit__ring--one"></span>
        <span class="auth-orbit__ring auth-orbit__ring--two"></span>

        <span class="auth-orbit__chip auth-orbit__chip--email">Email</span>
        <span class="auth-orbit__chip auth-orbit__chip--jwt">JWT</span>
        <span class="auth-orbit__chip auth-orbit__chip--pass">Password</span>
        <span class="auth-orbit__chip auth-orbit__chip--safe">2FA</span>
    </div>

    <div class="auth-orbit__card">
        <div class="auth-orbit__tabs">
            <button class="auth-orbit__tab active" data-mode="login">Вход</button>
            <button class="auth-orbit__tab" data-mode="register">Регистрация</button>
        </div>

        <form class="auth-orbit__form active" data-auth-form="login">
            <label>
                Email
                <input class="auth-orbit__email" type="email" placeholder="name@example.com">
            </label>

            <label>
                Пароль
                <div class="auth-orbit__password">
                    <input class="auth-orbit__password-input" type="password" placeholder="Введите пароль">
                    <button type="button" class="auth-orbit__toggle">Показать</button>
                </div>
            </label>

            <div class="auth-orbit__strength"><span></span></div>
            <p class="auth-orbit__hint">Введите email и пароль — интерфейс покажет состояние формы.</p>
            <button class="auth-orbit__submit" type="submit">Войти</button>
        </form>

        <form class="auth-orbit__form" data-auth-form="register">
            <label>
                Имя
                <input type="text" placeholder="Александр">
            </label>

            <label>
                Email
                <input class="auth-orbit__email" type="email" placeholder="name@example.com">
            </label>

            <label>
                Пароль
                <div class="auth-orbit__password">
                    <input class="auth-orbit__password-input" type="password" placeholder="Минимум 8 символов">
                    <button type="button" class="auth-orbit__toggle">Показать</button>
                </div>
            </label>

            <div class="auth-orbit__strength"><span></span></div>
            <p class="auth-orbit__hint">Проверьте email и надёжность пароля перед созданием аккаунта.</p>
            <button class="auth-orbit__submit" type="submit">Создать аккаунт</button>
        </form>
    </div>
</section>
.auth-orbit {
    min-height: 620px;
    display: grid;
    grid-template-columns: 0.95fr 1.05fr;
    gap: 36px;
    align-items: center;
    padding: 48px;
    border-radius: 28px;
    overflow: hidden;
    background:
        radial-gradient(circle at 15% 20%, rgba(37, 99, 235, 0.35), transparent 32%),
        radial-gradient(circle at 90% 90%, rgba(236, 72, 153, 0.22), transparent 34%),
        linear-gradient(135deg, #020617, #0f172a);
}

.auth-orbit__visual {
    position: relative;
    min-height: 420px;
    display: grid;
    place-items: center;
}

.auth-orbit__core {
    position: relative;
    z-index: 3;
    width: 190px;
    height: 190px;
    display: grid;
    place-items: center;
    text-align: center;
    border-radius: 50%;
    background: rgba(15, 23, 42, 0.86);
    border: 1px solid rgba(96, 165, 250, 0.5);
    box-shadow: 0 0 70px rgba(37, 99, 235, 0.42);
}

.auth-orbit__core strong {
    color: #ffffff;
    font-size: 42px;
    letter-spacing: -0.06em;
}

.auth-orbit__core small,
.auth-orbit__core span {
    color: #93c5fd;
    font-size: 13px;
}

.auth-orbit__ring {
    position: absolute;
    border-radius: 50%;
    border: 1px solid rgba(96, 165, 250, 0.32);
}

.auth-orbit__ring--one {
    width: 300px;
    height: 300px;
    animation: orbitSpin 12s linear infinite;
}

.auth-orbit__ring--two {
    width: 380px;
    height: 380px;
    border-color: rgba(236, 72, 153, 0.25);
    animation: orbitSpinReverse 18s linear infinite;
}

.auth-orbit__chip {
    position: absolute;
    z-index: 4;
    border: 1px solid rgba(148, 163, 184, 0.35);
    border-radius: 999px;
    padding: 9px 13px;
    color: #dbeafe;
    background: rgba(15, 23, 42, 0.8);
    box-shadow: 0 14px 40px rgba(2, 6, 23, 0.4);
}

.auth-orbit__chip--email { top: 70px; left: 65px; animation: orbitChipOne 12s linear infinite; }
.auth-orbit__chip--jwt { top: 92px; right: 55px; animation: orbitChipTwo 14s linear infinite; }
.auth-orbit__chip--pass { bottom: 90px; left: 40px; animation: orbitChipThree 13s linear infinite; }
.auth-orbit__chip--safe { bottom: 72px; right: 80px; animation: orbitChipFour 15s linear infinite; }

.auth-orbit.ready .auth-orbit__core {
    border-color: rgba(34, 197, 94, 0.8);
    box-shadow: 0 0 90px rgba(34, 197, 94, 0.35);
}

.auth-orbit.ready .auth-orbit__chip {
    border-color: rgba(34, 197, 94, 0.6);
}

.auth-orbit__card {
    padding: 28px;
    border-radius: 28px;
    border: 1px solid rgba(148, 163, 184, 0.28);
    background: rgba(15, 23, 42, 0.82);
    box-shadow: 0 30px 90px rgba(2, 6, 23, 0.6);
}

.auth-orbit__tabs {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
    margin-bottom: 22px;
}

.auth-orbit__tab {
    border: 1px solid #334155;
    border-radius: 999px;
    padding: 12px;
    color: #cbd5e1;
    background: transparent;
    cursor: pointer;
}

.auth-orbit__tab.active {
    color: #ffffff;
    border-color: #3b82f6;
    background: rgba(59, 130, 246, 0.22);
}

.auth-orbit__form {
    display: none;
}

.auth-orbit__form.active {
    display: grid;
    gap: 16px;
    animation: authFormFade 0.3s ease;
}

.auth-orbit__form label {
    display: grid;
    gap: 8px;
    color: #dbeafe;
    font-size: 14px;
}

.auth-orbit__form input {
    width: 100%;
    border: 1px solid #334155;
    border-radius: 16px;
    padding: 14px;
    color: #ffffff;
    background: #020617;
    outline: none;
}

.auth-orbit__form input:focus {
    border-color: #60a5fa;
    box-shadow: 0 0 0 4px rgba(59, 130, 246, 0.16);
}

.auth-orbit__password {
    display: flex;
    gap: 8px;
}

.auth-orbit__toggle {
    border: 1px solid #334155;
    border-radius: 14px;
    padding: 0 12px;
    color: #cbd5e1;
    background: #0f172a;
    cursor: pointer;
}

.auth-orbit__strength {
    height: 8px;
    overflow: hidden;
    border-radius: 999px;
    background: #020617;
    border: 1px solid #334155;
}

.auth-orbit__strength span {
    display: block;
    width: 0;
    height: 100%;
    border-radius: 999px;
    background: #ef4444;
    transition: 0.3s;
}

.auth-orbit__hint {
    margin: 0;
    color: #94a3b8;
    font-size: 14px;
}

.auth-orbit__submit {
    border: 0;
    border-radius: 16px;
    padding: 15px 18px;
    color: #ffffff;
    background: linear-gradient(135deg, #2563eb, #9333ea);
    cursor: pointer;
    transition: 0.25s;
}

.auth-orbit__submit:hover {
    transform: translateY(-2px);
}

@keyframes orbitSpin {
    to { transform: rotate(360deg); }
}

@keyframes orbitSpinReverse {
    to { transform: rotate(-360deg); }
}

@keyframes authFormFade {
    from { opacity: 0; transform: translateY(8px); }
    to { opacity: 1; transform: translateY(0); }
}

@keyframes orbitChipOne {
    0%, 100% { transform: translate(0, 0); }
    25% { transform: translate(18px, -12px); }
    50% { transform: translate(34px, 8px); }
    75% { transform: translate(10px, 18px); }
}

@keyframes orbitChipTwo {
    0%, 100% { transform: translate(0, 0); }
    25% { transform: translate(-18px, 14px); }
    50% { transform: translate(-32px, -6px); }
    75% { transform: translate(-10px, -18px); }
}

@keyframes orbitChipThree {
    0%, 100% { transform: translate(0, 0); }
    25% { transform: translate(16px, 16px); }
    50% { transform: translate(28px, -8px); }
    75% { transform: translate(6px, -20px); }
}

@keyframes orbitChipFour {
    0%, 100% { transform: translate(0, 0); }
    25% { transform: translate(-16px, -14px); }
    50% { transform: translate(-30px, 10px); }
    75% { transform: translate(-8px, 20px); }
}

@media (max-width: 768px) {
    .auth-orbit {
        grid-template-columns: 1fr;
        padding: 26px 18px;
    }

    .auth-orbit__visual {
        min-height: 330px;
    }

    .auth-orbit__ring--one {
        width: 230px;
        height: 230px;
    }

    .auth-orbit__ring--two {
        width: 290px;
        height: 290px;
    }

    .auth-orbit__chip {
        font-size: 12px;
        padding: 7px 10px;
    }

    .auth-orbit__password {
        flex-direction: column;
    }

    .auth-orbit__toggle {
        min-height: 42px;
    }
}
const authOrbit = document.querySelector(".auth-orbit");
const orbitTabs = document.querySelectorAll(".auth-orbit__tab");
const orbitForms = document.querySelectorAll(".auth-orbit__form");

function updateAuthState(form) {
    const email = form.querySelector(".auth-orbit__email");
    const password = form.querySelector(".auth-orbit__password-input");
    const strength = form.querySelector(".auth-orbit__strength span");
    const hint = form.querySelector(".auth-orbit__hint");

    const emailReady = email.value.includes("@") && email.value.includes(".");
    const value = password.value;

    let score = 0;
    if (value.length >= 8) score += 25;
    if (/[A-ZА-Я]/.test(value)) score += 25;
    if (/[0-9]/.test(value)) score += 25;
    if (/[^A-Za-zА-Яа-я0-9]/.test(value)) score += 25;

    strength.style.width = score + "%";

    if (score < 50) {
        strength.style.background = "#ef4444";
    } else if (score < 75) {
        strength.style.background = "#f59e0b";
    } else {
        strength.style.background = "#22c55e";
    }

    if (emailReady && score >= 75) {
        authOrbit.classList.add("ready");
        hint.textContent = "Форма готова. В реальном проекте данные отправляются на сервер.";
        hint.style.color = "#86efac";
    } else {
        authOrbit.classList.remove("ready");
        hint.textContent = "Введите корректный email и более надёжный пароль.";
        hint.style.color = "#94a3b8";
    }
}

orbitTabs.forEach(function (tab) {
    tab.addEventListener("click", function () {
        const mode = tab.dataset.mode;

        orbitTabs.forEach(item => item.classList.remove("active"));
        orbitForms.forEach(form => form.classList.remove("active"));

        tab.classList.add("active");
        document.querySelector('[data-auth-form="' + mode + '"]').classList.add("active");
    });
});

orbitForms.forEach(function (form) {
    const email = form.querySelector(".auth-orbit__email");
    const password = form.querySelector(".auth-orbit__password-input");
    const toggle = form.querySelector(".auth-orbit__toggle");

    email.addEventListener("input", () => updateAuthState(form));
    password.addEventListener("input", () => updateAuthState(form));

    toggle.addEventListener("click", function () {
        const isHidden = password.type === "password";
        password.type = isHidden ? "text" : "password";
        toggle.textContent = isHidden ? "Скрыть" : "Показать";
    });

    form.addEventListener("submit", function (event) {
        event.preventDefault();
        updateAuthState(form);
    });
});
🚀 Рассчитать проект