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-submit-feedback.md

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

Provide Clear Form Submission Feedback

Impact: HIGH (Prevents user confusion and double submissions)

Provide clear, immediate feedback when users submit forms. Users should always know the current state: submitting, success, or failure.

Incorrect

<!-- ❌ Bad: No submission feedback -->
<form onsubmit="submitForm()">
  <input type="email" name="email" required>
  <button type="submit">Subscribe</button>
</form>

<script>
async function submitForm() {
  // No loading indication
  const response = await fetch('/api/subscribe', {
    method: 'POST',
    body: new FormData(form)
  });

  // Silent success - user doesn't know it worked
  if (response.ok) {
    console.log('Success');
  }

  // Unhelpful error
  if (!response.ok) {
    alert('Error');
  }
}
</script>
<!-- ❌ Bad: Confusing states -->
<form>
  <input type="email" name="email">
  <!-- Button changes but no visual feedback -->
  <button type="submit" id="btn">Subscribe</button>
</form>

<script>
btn.textContent = 'Sending...';
// User can click multiple times
// No disabled state
// Page reloads on error, losing context
</script>

Problems:

  • No loading indicator leaves users wondering if the form submitted
  • Silent success provides no confirmation that the action worked
  • Generic alert('Error') gives no actionable guidance
  • Button is not disabled during submission, allowing double-clicks
  • Page reload on error loses all entered data

Correct

<!-- ✅ Good: Comprehensive submission feedback -->
<form id="newsletter-form" novalidate>
  <div class="form-group">
    <label for="email">Email Address</label>
    <input type="email"
           id="email"
           name="email"
           required
           aria-required="true"
           aria-describedby="email-error"
           autocomplete="email">
    <p id="email-error" class="error" hidden></p>
  </div>

  <button type="submit"
          id="submit-btn"
          aria-describedby="submit-status">
    <span class="btn-text">Subscribe</span>
    <span class="btn-loading" hidden>
      <svg class="spinner" aria-hidden="true" viewBox="0 0 24 24">
        <circle cx="12" cy="12" r="10" fill="none" stroke="currentColor" stroke-width="3"/>
      </svg>
      <span>Subscribing...</span>
    </span>
  </button>

  <!-- Status message for screen readers -->
  <div id="submit-status"
       role="status"
       aria-live="polite"
       class="visually-hidden">
  </div>
</form>

<!-- Success state (shown after successful submission) -->
<div id="success-message" class="success-panel" tabindex="-1" hidden>
  <svg class="success-icon" aria-hidden="true" viewBox="0 0 24 24">
    <path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z" fill="currentColor"/>
  </svg>
  <h2>You're subscribed!</h2>
  <p>Check your inbox for a confirmation email.</p>
  <button type="button" onclick="resetForm()">Subscribe another email</button>
</div>

<script>
const form = document.getElementById('newsletter-form');
const submitBtn = document.getElementById('submit-btn');
const btnText = submitBtn.querySelector('.btn-text');
const btnLoading = submitBtn.querySelector('.btn-loading');
const statusEl = document.getElementById('submit-status');
const successMessage = document.getElementById('success-message');

form.addEventListener('submit', async (e) => {
  e.preventDefault();

  // Validate
  const email = document.getElementById('email');
  if (!email.validity.valid) {
    showError(email, 'Please enter a valid email address');
    return;
  }

  // Set loading state
  setLoadingState(true);

  try {
    const response = await fetch('/api/subscribe', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ email: email.value })
    });

    const data = await response.json();

    if (response.ok) {
      showSuccess();
    } else {
      // Server returned an error
      showError(email, data.message || 'Subscription failed. Please try again.');
      setLoadingState(false);
    }
  } catch (error) {
    // Network or other error
    showError(email, 'Network error. Please check your connection and try again.');
    setLoadingState(false);
  }
});

function setLoadingState(isLoading) {
  submitBtn.disabled = isLoading;
  submitBtn.setAttribute('aria-busy', isLoading);
  btnText.hidden = isLoading;
  btnLoading.hidden = !isLoading;

  // Announce to screen readers
  if (isLoading) {
    statusEl.textContent = 'Submitting your subscription...';
  }
}

function showSuccess() {
  form.hidden = true;
  successMessage.hidden = false;

  // Announce success
  statusEl.textContent = 'Success! You have been subscribed to our newsletter.';

  // Focus the success message for accessibility
  successMessage.focus();
}

function showError(input, message) {
  const errorEl = document.getElementById(`${input.id}-error`);
  input.setAttribute('aria-invalid', 'true');
  errorEl.textContent = message;
  errorEl.hidden = false;
  input.focus();

  // Announce error
  statusEl.textContent = `Error: ${message}`;
}

function resetForm() {
  form.reset();
  form.hidden = false;
  successMessage.hidden = true;
  document.getElementById('email').focus();
}
</script>

<style>
/* Loading spinner animation */
@keyframes spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

.spinner {
  width: 1rem;
  height: 1rem;
  animation: spin 1s linear infinite;
}

.spinner circle {
  stroke-dasharray: 50;
  stroke-dashoffset: 20;
}

/* Button states */
button[type="submit"] {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  min-width: 140px;
  justify-content: center;
}

button[type="submit"]:disabled {
  opacity: 0.7;
  cursor: wait;
}

/* Success panel */
.success-panel {
  text-align: center;
  padding: 2rem;
  background: #f0fdf4;
  border: 2px solid #22c55e;
  border-radius: 8px;
}

.success-icon {
  width: 48px;
  height: 48px;
  color: #22c55e;
}

/* Focus for success panel */
.success-panel:focus {
  outline: 3px solid #22c55e;
  outline-offset: 2px;
}
</style>

Benefits:

  • Loading state with disabled button prevents double submissions
  • Screen reader users are notified of state changes via ARIA live regions
  • Clear success confirmation builds user confidence
  • Specific error messages with recovery guidance help users fix issues
  • Form data is preserved on error so users do not need to retype

Reference: web.dev - Form Submission

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