Lesson 33 / Interaction
UI States and Feedback
Design clear default, hover, focus, active, current, loading, empty, error, success, and disabled states so interfaces communicate what is happening.
Course Role
Studio Support
Best during work sessions, critique, debugging, project planning, or final polish.
Teacher Notes / In-Class Use
Demo Live
- Walk through the interactive demo before students start changing their own project files.
- Connect the demo back to the first goal: Identify common UI states and when each one is needed
Try In Class
- Audit one page and list missing states for buttons, links, navigation, and form inputs.
- Have students make one visible change, save, refresh, and explain what changed.
Submit Or Check
- Ask students to show the work in the browser, not only in the editor.
- Have students commit their progress with a clear message when the checkpoint is stable.
Watch For
- Students copying code without checking file paths, spelling, or capitalization.
- Visual changes that work locally but break when the project is published.
Learning Goals
- Identify common UI states and when each one is needed
- Style states for buttons, links, navigation, forms, cards, and dynamic content
- Write helpful feedback messages for empty, loading, success, and error states
- Check interactive states for keyboard access, contrast, motion, and clarity
Interactive Demo
How to use this demo.
Use the demo as a small lab. Change one thing, observe the result, then connect it back to your own project.
What To Try
- Switch through each UI state and compare the button, input, and feedback message.
- Pause on focus, loading, error, and disabled because those states are often missed.
What Changes
- The preview changes visual styling, disabled behavior, and message content.
- The code sample shows a pattern connected to the selected state.
What To Notice
- A state is not only decoration; it communicates what is possible or what just happened.
- Helpful messages explain the next step instead of only saying Error or Failed.
Apply It
- Audit one project page and add missing hover, focus, loading, empty, error, or success states.
Interactive Demo
UI States Lab
Switch component states and compare the visual feedback, message, and code pattern.
Ready to save.
.button:focus-visible { outline: 3px solid currentColor; } This demo uses extra JavaScript for teaching. The code sample shows the pattern to practice. View full demo source.
Interfaces Need Feedback
A user should never wonder whether something is clickable, whether an action worked, or what to do next. UI states make interaction visible.
Good feedback is part of the design, not a final decoration. A button, link, card, form, or navigation item should communicate what it can do before and after someone interacts with it.
Start With The Default State
Every component starts in a default state. Before adding hover or animation, make sure the default version already looks usable and understandable.
- A button should look clickable before hover.
- A link should look like a link before hover.
- A form input should look editable before focus.
- A card should make it clear whether the whole card is clickable or only a link inside it.
Common States
| State | Meaning | Example |
|---|---|---|
| Default | The normal resting appearance. | Button has a clear shape, label, and contrast. |
| Hover | Pointer is over an interactive element. | Button background changes. |
| Focus | Keyboard focus is on an element. | Outline appears on a link or input. |
| Active or pressed | Element is being clicked, tapped, or pressed. | Button moves slightly or darkens while pressed. |
| Current | Element represents the current page, tab, or selected item. | Current nav link is marked. |
| Loading | The system is working. | Button says Saving... and prevents duplicate clicks. |
| Empty | There is no content yet. | A gallery says no projects have been added. |
| Error | Something needs correction. | Form field explains what to fix. |
| Success | An action completed. | Message says the project was saved. |
| Disabled | An action is unavailable. | Submit button is disabled until required fields are complete. |
Active Is Not Current
Active and current are easy to mix up. Active usually means something is being pressed right now. Current means the item represents the page, section, tab, or filter that is selected.
| State | Use It For | Example |
|---|---|---|
| Active or pressed | Short interaction feedback. | A button darkens while the mouse button is down. |
| Current | Orientation inside an interface. | The About link is highlighted while the user is on about.html. |
Button States
Buttons need clear default, hover, focus, active, disabled, and sometimes loading states. Focus matters because not everyone uses a mouse.
.button {
background: #2457d6;
color: #ffffff;
border: 0;
border-radius: 0.375rem;
padding: 0.75rem 1rem;
font: inherit;
cursor: pointer;
}
.button:hover {
background: #1742a4;
}
.button:focus-visible {
outline: 3px solid currentColor;
outline-offset: 3px;
}
.button:active {
transform: translateY(1px);
}
.button:disabled {
cursor: not-allowed;
opacity: 0.55;
} Focus Visible
Hover helps mouse users. Focus helps keyboard users. Do not remove the browser outline unless you replace it with a visible focus style.
- Use :focus-visible for keyboard-friendly focus styling.
- Make the focus style easy to see against the background.
- Test with Tab, Shift + Tab, Enter, and Space.
- Focus should appear on links, buttons, form controls, and custom interactive elements.
Link States
Links should be recognizable and usable in every state. Avoid making links depend only on color when they appear inside paragraph text.
a {
color: #1659c7;
text-decoration: underline;
text-underline-offset: 0.15em;
}
a:visited {
color: #6b3fb5;
}
a:hover,
a:focus-visible {
color: #0d347a;
text-decoration-thickness: 0.15em;
} Current Navigation
A current navigation state helps users know where they are. It should be visible without relying only on color.
<nav aria-label="Main navigation">
<a href="index.html">Home</a>
<a href="menu.html" aria-current="page">Menu</a>
<a href="contact.html">Contact</a>
</nav> Form Feedback
Form feedback should be specific and connected to the field it describes. Users should know what went wrong and how to fix it.
- Required fields should be clear before submission.
- Error messages should explain the fix.
- Success messages should confirm what happened.
- Helper text should make the expected input easier to understand.
- aria-describedby can connect help or error text to the input.
<label for="email">Email</label>
<p id="email-help">Use an address you check often.</p>
<input
id="email"
name="email"
type="email"
required
aria-describedby="email-help email-error"
aria-invalid="true"
>
<p id="email-error">Enter an email address that includes an @ symbol.</p> Loading States
Loading states tell users that the system is working. They also prevent people from clicking the same action repeatedly because nothing appears to be happening.
- Change button text from Submit to Sending... or Save to Saving... when work is in progress.
- Disable repeated submit actions while loading when appropriate.
- Use skeletons or placeholders for content that will appear soon.
- Keep loading messages short and specific.
<button class="button" disabled aria-busy="true">Saving...</button> Empty States
An empty state appears when there is no content to show yet. A good empty state explains what happened and gives the user a useful next step.
| Situation | Helpful Empty State |
|---|---|
| Empty project gallery | No projects have been added yet. Add your first project to get started. |
| No search results | No results matched sushi. Try a different search term or clear the filters. |
| Empty cart | Your cart is empty. Browse the menu to add an item. |
| No saved favorites | You have not saved any favorites yet. Tap the heart icon to save one. |
Disabled State Caution
Disabled controls can be frustrating when users do not know why the control is disabled. Use disabled states carefully and explain what is needed when the reason is not obvious.
- A disabled button should still be readable.
- Do not use opacity so low that the label becomes hard to read.
- Add helper text when the user needs to complete another step first.
- Sometimes an enabled button with a helpful error message is clearer than a disabled button with no explanation.
Writing Feedback
Good feedback messages are specific, human, and useful. They tell the user what happened or how to fix the problem.
| Weak Message | Better Message |
|---|---|
| Error | Enter an email address that includes an @ symbol. |
| Invalid | Password must be at least 8 characters. |
| Failed | The image did not upload. Try a smaller JPG or PNG file. |
| Done | Project saved. You can keep editing or submit it. |
| No items | No projects have been added yet. Add your first project to get started. |
Motion And Micro-Interactions
Small transitions can make feedback feel smoother, but motion should support the interaction instead of distracting from it.
- Use short transitions for hover, focus, opening, closing, and loading feedback.
- Avoid large motion for essential actions like form errors.
- Respect reduced-motion preferences.
- Do not hide important information behind animation timing.
.button {
transition: background-color 160ms ease, transform 160ms ease;
}
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
scroll-behavior: auto !important;
transition-duration: 0.01ms !important;
}
} Accessibility Checklist
- Interactive elements have visible keyboard focus.
- Color is not the only cue for links, errors, current pages, or success states.
- Form help and error messages are connected to their inputs when possible.
- Disabled states are understandable and readable.
- Loading states prevent duplicate actions when needed.
- Motion is subtle and respects prefers-reduced-motion.
- Messages explain what happened or what to do next.
Component State Checklist
| Component | States To Check |
|---|---|
| Buttons | Default, hover, focus, active, disabled, loading. |
| Links | Default, visited, hover, focus, active. |
| Navigation | Default, hover, focus, current. |
| Form inputs | Default, focus, required, invalid, error, success, disabled. |
| Cards | Default, hover or focus if clickable, selected if part of a set. |
| Lists or galleries | Default content, empty state, loading state, error state if data can fail. |
Checkpoint
Before moving on, make sure these feel true.
- I can identify hover, focus, active, loading, empty, error, success, and disabled states.
- I can style visible states for interactive elements.
- I can write feedback messages that explain what happened and what to do next.
Practice
- Audit one page and list missing states for buttons, links, navigation, and form inputs.
- Add hover and focus-visible states to every button and link in a project.
- Create a current state for the active navigation link.
- Create one empty state for a list, gallery, cart, or search result page.
- Rewrite one vague error message so it explains the fix.
- Add a loading state to a button or content area.
- Test the page with Tab, Shift + Tab, Enter, and Space.