Links, Buttons, and Navigation Styling

Introduction

Links, buttons, and navigation controls are the core interaction layer of most websites. If these elements look unclear or behave inconsistently, users get lost quickly. This chapter covers practical styling patterns for interactive controls with strong focus on clarity, state feedback, and accessibility.

Prerequisites

  • Basic pseudo-classes (:hover, :focus-visible, :active)
  • Basic spacing and typography styling
  • Familiarity with responsive layout fundamentals

Before styling, keep semantics correct:

  • use <a> for navigation to another URL/location
  • use <button> for in-page actions (toggle, submit, open modal)

Styling can make them look similar, but behavior and accessibility expectations differ.

A good baseline:

Code explanation:

  • underline preserves link discoverability in content text
  • hover and focus-visible provide clear interaction feedback
  • keyboard users get visible focus ring

Avoid removing underlines globally unless you provide equally clear alternatives.

css
a:visited {
  color: #7c3aed;
}
 
a[target="_blank"]::after {
  content: " ↗";
  font-size: 0.9em;
}

This can help users understand browsing history and external navigation behavior.

Use subtle cues; avoid visual clutter in dense text blocks.

Button Baseline Style

Code explanation:

  • inline-flex aligns icon + label cleanly
  • min-height: 44px improves touch usability
  • cursor: pointer clarifies clickability
  • transition supports smooth state changes

Button Interaction States

Use distinct visual states for hover, active, focus, and disabled to avoid ambiguity.

Button Variants

Example variant system:

Keep variant count small and purposeful for consistent UX.

Simple horizontal nav:

css
.nav {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

Responsive baseline:

css
@media (max-width: 700px) {
  .nav {
    flex-wrap: wrap;
  }
}

For more advanced responsive nav patterns, pair with disclosure toggles and clear focus order.

Padding makes click targets easier to use than plain text-only links.

Active Navigation State

You can mark current page with aria-current="page":

css
.nav a[aria-current="page"] {
  background: #dbeafe;
  color: #1e3a8a;
  font-weight: 600;
}

This is more robust than relying on color-only hover behavior.

Accessibility-friendly top skip link:

This helps keyboard users jump directly to main content.

Focus Visibility and Contrast Rules

Interaction styling should always preserve:

  • visible keyboard focus
  • readable text/background contrast
  • clear affordance difference between normal and interactive elements

Do not style links/buttons to look like plain body text without extra cues.

Warning

Do Not Remove Focus Ring Globally

If default focus styles are removed, replace them immediately with strong custom :focus-visible styles.

Responsive Navigation Considerations

On narrow screens:

  • increase tap target size
  • avoid crowded horizontal menus
  • keep primary actions visible
  • ensure menu toggles are keyboard accessible

Even simple wrap behavior can be better than forcing tiny unreadable nav text.

Common Mistakes

MistakeWhy it hurtsBetter approach
Styling <a> and <button> interchangeably without semanticsAccessibility/behavior mismatchUse correct element semantics first
Removing underlines from all linksReduced discoverabilityKeep underlines in content text
No focus-visible stylesKeyboard navigation becomes unclearAdd clear focus ring for interactive controls
Tiny click targetsHard mobile interactionKeep comfortable padding/min-height
Disabled state only by color changeAmbiguous and inaccessibleCombine opacity/cursor/state semantics

Debugging Interaction Styles

When controls feel inconsistent:

  1. verify semantic element choice (a vs button)
  2. force states in DevTools (:hover, :active, :focus-visible)
  3. check specificity/order conflicts in state styles
  4. test keyboard tab sequence and visibility
  5. test touch interaction on real mobile device

State testing should be part of every UI review.

Mini Exercise

  1. Build a nav bar with 4 links and one primary action button
  2. Add hover + focus-visible states for all interactive items
  3. Mark one nav link with aria-current="page" and style it
  4. Add a skip link to main content
  5. Verify keyboard-only navigation from top to bottom

FAQ

Yes, if it still performs navigation. Keep semantic element correct and preserve focus/interaction cues.

In body text, usually yes. In nav bars/buttons, alternative strong cues can be acceptable.

Why use aria-current="page" in nav?

It helps assistive technologies identify current location and allows robust active-state styling.

Is :focus-visible enough by itself?

For most modern browsers, yes for interactive focus styling. Consider fallback strategy if your support matrix requires it.

What is the best minimum touch target size?

A common practical target is around 44px in at least one dimension for comfortable tap interaction.