All skills
asyrafhussin avatar

/web-design-guidelines

@b73c638

UI/UX best practices and accessibility audit. Use when reviewing UI code, checking accessibility, running accessibility audits, auditing forms, or ensuring web interface best practices. Triggers on "audit accessibility", "check WCAG", "review UI", "check accessibility", "audit design", "review UX", or "check best practices".

Use this Skill: https://skilld.dev/gh/asyrafhussin/agent-skills/web-design-guidelines

This session only. Nothing lands on disk.

rulesform-validation-ux.md

≈1.9k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Design User-Friendly Form Validation

Impact: HIGH (Reduces form abandonment by 20-30%)

Design form validation that helps users succeed. Good validation provides clear feedback, prevents frustration, and guides users to correct errors efficiently.

Incorrect

<!-- ❌ Bad: Poor validation UX -->
<form onsubmit="return validateForm()">
  <input type="text" id="email" placeholder="Email">
  <input type="text" id="password" placeholder="Password">
  <button type="submit">Sign Up</button>
</form>

<script>
function validateForm() {
  // Only validates on submit
  const email = document.getElementById('email').value;
  const password = document.getElementById('password').value;

  // Generic, unhelpful error message
  if (!email || !password) {
    alert('Please fill in all fields');
    return false;
  }

  // Regex-only validation with no feedback
  if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
    alert('Invalid email');
    return false;
  }

  // Unclear requirements
  if (password.length < 8) {
    alert('Password too short');
    return false;
  }

  return true;
}
</script>

<style>
/* Error state with no guidance */
.error { border-color: red; }
</style>

Problems:

  • Submit-only validation delays all feedback until the end
  • JavaScript alert() provides no field-level context and interrupts the user
  • Generic messages ("Invalid email") do not explain how to fix the error
  • Password requirements are hidden until the user fails
  • No ARIA attributes to communicate errors to screen readers

Correct

<!-- ✅ Good: User-friendly validation -->
<form id="signup-form" novalidate>
  <div class="form-group">
    <label for="email">
      Email Address
      <span class="required" aria-hidden="true">*</span>
    </label>
    <input type="email"
           id="email"
           name="email"
           required
           aria-required="true"
           aria-describedby="email-hint email-error"
           autocomplete="email">
    <p id="email-hint" class="hint">We'll send your confirmation here</p>
    <p id="email-error" class="error-message" role="alert" hidden></p>
  </div>

  <div class="form-group">
    <label for="password">
      Password
      <span class="required" aria-hidden="true">*</span>
    </label>
    <input type="password"
           id="password"
           name="password"
           required
           aria-required="true"
           aria-describedby="password-requirements password-error"
           minlength="8"
           autocomplete="new-password">

    <!-- Show requirements upfront, not just on error -->
    <div id="password-requirements" class="requirements">
      <p>Password must contain:</p>
      <ul>
        <li id="req-length" class="requirement">
          <span class="icon" aria-hidden="true"></span>
          At least 8 characters
        </li>
        <li id="req-uppercase" class="requirement">
          <span class="icon" aria-hidden="true"></span>
          One uppercase letter
        </li>
        <li id="req-number" class="requirement">
          <span class="icon" aria-hidden="true"></span>
          One number
        </li>
      </ul>
    </div>
    <p id="password-error" class="error-message" role="alert" hidden></p>
  </div>

  <div class="form-group">
    <label for="confirm-password">
      Confirm Password
      <span class="required" aria-hidden="true">*</span>
    </label>
    <input type="password"
           id="confirm-password"
           name="confirmPassword"
           required
           aria-required="true"
           aria-describedby="confirm-error"
           autocomplete="new-password">
    <p id="confirm-error" class="error-message" role="alert" hidden></p>
  </div>

  <button type="submit" id="submit-btn">Create Account</button>
</form>

<script>
const form = document.getElementById('signup-form');
const emailInput = document.getElementById('email');
const passwordInput = document.getElementById('password');
const confirmInput = document.getElementById('confirm-password');

// Validate on blur (when leaving field)
emailInput.addEventListener('blur', validateEmail);
passwordInput.addEventListener('input', validatePassword);
confirmInput.addEventListener('blur', validateConfirmPassword);

// Also validate on submit
form.addEventListener('submit', function(e) {
  e.preventDefault();

  const isEmailValid = validateEmail();
  const isPasswordValid = validatePassword();
  const isConfirmValid = validateConfirmPassword();

  if (isEmailValid && isPasswordValid && isConfirmValid) {
    // submit form logic here
  } else {
    // Focus first invalid field
    const firstError = form.querySelector('[aria-invalid="true"]');
    if (firstError) firstError.focus();
  }
});

function validateEmail() {
  const email = emailInput.value.trim();
  const errorEl = document.getElementById('email-error');

  if (!email) {
    showError(emailInput, errorEl, 'Email address is required');
    return false;
  }

  if (!isValidEmail(email)) {
    showError(emailInput, errorEl, 'Please enter a valid email address (e.g., name@example.com)');
    return false;
  }

  clearError(emailInput, errorEl);
  return true;
}

function validatePassword() {
  const password = passwordInput.value;
  const requirements = {
    length: password.length >= 8,
    uppercase: /[A-Z]/.test(password),
    number: /[0-9]/.test(password)
  };

  // Update requirement indicators in real-time
  updateRequirement('req-length', requirements.length);
  updateRequirement('req-uppercase', requirements.uppercase);
  updateRequirement('req-number', requirements.number);

  const allMet = Object.values(requirements).every(Boolean);

  if (allMet) {
    passwordInput.setAttribute('aria-invalid', 'false');
    return true;
  }

  passwordInput.setAttribute('aria-invalid', 'true');
  return false;
}

function validateConfirmPassword() {
  const password = passwordInput.value;
  const confirm = confirmInput.value;
  const errorEl = document.getElementById('confirm-error');

  if (!confirm) {
    showError(confirmInput, errorEl, 'Please confirm your password');
    return false;
  }

  if (confirm !== password) {
    showError(confirmInput, errorEl, 'Passwords do not match');
    return false;
  }

  clearError(confirmInput, errorEl);
  return true;
}

function updateRequirement(id, met) {
  const el = document.getElementById(id);
  el.classList.toggle('met', met);
  el.classList.toggle('unmet', !met);
}

function showError(input, errorEl, message) {
  input.setAttribute('aria-invalid', 'true');
  errorEl.textContent = message;
  errorEl.hidden = false;
}

function clearError(input, errorEl) {
  input.setAttribute('aria-invalid', 'false');
  errorEl.hidden = true;
}

function isValidEmail(email) {
  return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
}
</script>

<style>
.requirement.met .icon::before { content: '✓'; color: green; }
.requirement.unmet .icon::before { content: '○'; color: #666; }
.error-message { color: #dc2626; }
</style>

Benefits:

  • Blur validation provides feedback at the right moment without interrupting typing
  • Password requirements are shown upfront so users know what is expected
  • Real-time requirement indicators give positive feedback as criteria are met
  • Specific, actionable error messages guide users to correct input
  • Focus moves to the first invalid field on submit for efficient error correction

Reference: web.dev - Best Practices for Form Validation

Source: SKILL.md on GitHub

2 warnings16d5 checks · Risk SAFE
  • Gen Agent Trust Hub16d

    The skill provides comprehensive guidelines for accessibility and web design audits. It processes user-provided code files to generate compliance reports, which introduces a minor risk of indirect prompt injection if the audited files contain malicious instructions. No evidence of data exfiltration, obfuscation, or unauthorized command execution was found.

  • Socket16d

    2 alerts: gptAnomaly

  • Snyk16d

    Risk: LOW · No issues

  • Runlayer7mo

    26/27 files flagged

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at b73c638. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub last month.

Steadyupdated 6 months ago
metadata
{
  "author": "agent-skills",
  "version": "2.1.0"
}

README badge

README badge for asyrafhussin/agent-skills/web-design-guidelines