Skillversitas

CSS Links - Link Styling

Links are the most basic element of the web. CSS gives you full control over how links look in various states — normal, visited, while hovered, while clicked, and while focused. A solid understanding of link pseudo-classes is essential for building interactive and accessible websites.

The correct order for link pseudo-classes is LVHA — Link, Visited, Hover, Active. Changing this order can cause styles to stop working correctly because of the CSS cascade.

In addition, :focus is very important for accessibility so keyboard users can see which element is currently active.


Code Example

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>CSS Links</title>
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    body {
      font-family: 'Segoe UI', Tahoma, sans-serif;
      padding: 30px;
      background: #f0f2f5;
      color: #334155;
    }

    h2 {
      margin-bottom: 15px;
      color: #1a1a2e;
    }

    .section {
      margin-bottom: 40px;
      background: white;
      padding: 25px;
      border-radius: 12px;
      box-shadow: 0 2px 10px rgba(0,0,0,0.08);
    }

    .label {
      font-size: 12px;
      color: #64748b;
      margin-bottom: 10px;
      font-family: monospace;
      background: #e2e8f0;
      display: inline-block;
      padding: 3px 8px;
      border-radius: 4px;
      margin-bottom: 15px;
    }

    /* ===== BASIC LINK STYLES (LVHA) ===== */
    .basic-link {
      color: #667eea;
      text-decoration: none;
      transition: color 0.3s;
    }

    .basic-link:link {
      color: #667eea;
    }

    .basic-link:visited {
      color: #764ba2;
    }

    .basic-link:hover {
      color: #f5576c;
    }

    .basic-link:active {
      color: #ff6b6b;
    }

    /* ===== UNDERLINE ON HOVER ===== */
    .underline-link {
      color: #1e293b;
      text-decoration: none;
      position: relative;
      padding-bottom: 2px;
    }

    .underline-link::after {
      content: '';
      position: absolute;
      bottom: 0;
      left: 0;
      width: 0;
      height: 2px;
      background: #667eea;
      transition: width 0.3s;
    }

    .underline-link:hover::after {
      width: 100%;
    }

    .underline-link:hover {
      color: #667eea;
    }

    /* ===== BUTTON STYLE LINKS ===== */
    .btn-link {
      display: inline-block;
      padding: 10px 24px;
      background: #667eea;
      color: white;
      text-decoration: none;
      border-radius: 8px;
      font-weight: 600;
      transition: all 0.3s;
    }

    .btn-link:hover {
      background: #5a67d8;
      transform: translateY(-2px);
      box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
    }

    .btn-link:active {
      transform: translateY(0);
      box-shadow: 0 2px 6px rgba(102, 126, 234, 0.3);
    }

    .btn-link:focus {
      outline: 3px solid #c7d2fe;
      outline-offset: 2px;
    }

    .btn-outline-link {
      display: inline-block;
      padding: 10px 24px;
      background: transparent;
      color: #667eea;
      text-decoration: none;
      border: 2px solid #667eea;
      border-radius: 8px;
      font-weight: 600;
      transition: all 0.3s;
    }

    .btn-outline-link:hover {
      background: #667eea;
      color: white;
    }

    /* ===== FOCUS STATE (ACCESSIBILITY) ===== */
    .accessible-link {
      color: #667eea;
      text-decoration: underline;
      padding: 4px 8px;
      border-radius: 4px;
      transition: all 0.2s;
    }

    .accessible-link:focus {
      outline: 3px solid #667eea;
      outline-offset: 2px;
      background: #eef2ff;
    }

    .accessible-link:focus:not(:focus-visible) {
      outline: none;
      background: none;
    }

    .accessible-link:focus-visible {
      outline: 3px solid #667eea;
      outline-offset: 2px;
      background: #eef2ff;
    }

    /* ===== LINK GROUPS ===== */
    .link-list {
      list-style: none;
      display: flex;
      gap: 20px;
      flex-wrap: wrap;
    }

    .link-list a {
      color: #475569;
      text-decoration: none;
      padding: 8px 16px;
      border-radius: 6px;
      transition: all 0.3s;
    }

    .link-list a:hover {
      background: #f1f5f9;
      color: #667eea;
    }

    .link-list a.active {
      background: #667eea;
      color: white;
    }

    /* ===== NAVIGATION LINKS ===== */
    .nav-demo {
      display: flex;
      gap: 5px;
      background: #1a1a2e;
      padding: 10px;
      border-radius: 10px;
    }

    .nav-demo a {
      color: #cbd5e1;
      text-decoration: none;
      padding: 10px 20px;
      border-radius: 6px;
      transition: all 0.3s;
      font-weight: 500;
    }

    .nav-demo a:hover {
      background: rgba(255,255,255,0.1);
      color: white;
    }

    .nav-demo a.active {
      background: #667eea;
      color: white;
    }

    /* ===== BREADCRUMB ===== */
    .breadcrumb {
      display: flex;
      align-items: center;
      gap: 8px;
      list-style: none;
      font-size: 14px;
    }

    .breadcrumb a {
      color: #667eea;
      text-decoration: none;
      transition: color 0.2s;
    }

    .breadcrumb a:hover {
      color: #5a67d8;
      text-decoration: underline;
    }

    .breadcrumb .separator {
      color: #cbd5e1;
    }

    .breadcrumb .current {
      color: #64748b;
      pointer-events: none;
    }

    /* ===== FOOTER LINKS ===== */
    .footer-links {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
      gap: 30px;
      background: #1e293b;
      padding: 40px;
      border-radius: 12px;
    }

    .footer-links h4 {
      color: white;
      margin-bottom: 15px;
      font-size: 14px;
      text-transform: uppercase;
      letter-spacing: 0.5px;
    }

    .footer-links ul {
      list-style: none;
    }

    .footer-links li {
      margin-bottom: 10px;
    }

    .footer-links a {
      color: #94a3b8;
      text-decoration: none;
      font-size: 14px;
      transition: all 0.3s;
      display: inline-block;
    }

    .footer-links a:hover {
      color: #818cf8;
      transform: translateX(4px);
    }

    /* ===== LINK ICON ===== */
    .icon-link {
      color: #667eea;
      text-decoration: none;
      display: inline-flex;
      align-items: center;
      gap: 6px;
      font-weight: 600;
      transition: gap 0.3s;
    }

    .icon-link:hover {
      gap: 10px;
      color: #5a67d8;
    }

    .icon-link::after {
      content: '→';
    }

    .icon-link-back::after {
      content: none;
    }

    .icon-link-back::before {
      content: '←';
    }

    /* ===== BADGE LINK ===== */
    .badge-link {
      display: inline-flex;
      align-items: center;
      gap: 6px;
      color: #475569;
      text-decoration: none;
      padding: 6px 14px;
      background: #f1f5f9;
      border-radius: 20px;
      font-size: 14px;
      transition: all 0.3s;
    }

    .badge-link:hover {
      background: #667eea;
      color: white;
    }

    .badge-link .count {
      background: #667eea;
      color: white;
      padding: 2px 8px;
      border-radius: 10px;
      font-size: 12px;
      font-weight: bold;
    }

    .badge-link:hover .count {
      background: white;
      color: #667eea;
    }

    .link-group {
      display: flex;
      flex-wrap: wrap;
      gap: 10px;
      margin-top: 15px;
    }

    .link-examples {
      display: flex;
      flex-direction: column;
      gap: 15px;
      margin-top: 15px;
    }
  </style>
</head>
<body>
  <!-- Basic LVHA -->
  <div class="section">
    <h2>Basic Link — LVHA Order</h2>
    <span class="label">:link → :visited → :hover → :active</span>
    <p style="margin-bottom: 15px; color: #64748b;">
      The order of pseudo-classes is <strong>very important</strong>. If the order is wrong, the styles will not work because of the CSS cascade.
    </p>
    <div class="link-examples">
      <a href="#" class="basic-link">Normal Link (not visited)</a>
      <a href="https://google.com" class="basic-link">Link Sudah Dikunjungi (visited)</a>
    </div>
  </div>

  <!-- Underline Animation -->
  <div class="section">
    <h2>Underline Animation</h2>
    <span class="label">::after pseudo-element + transition</span>
    <div class="link-examples">
      <a href="#" class="underline-link">Hover me for an underline animation</a>
      <a href="#" class="underline-link">This animation uses the ::after pseudo-element</a>
      <a href="#" class="underline-link">Width changes from 0 to 100%</a>
    </div>
  </div>

  <!-- Button Style Links -->
  <div class="section">
    <h2>Button Style Links</h2>
    <span class="label">display: inline-block + padding + border-radius</span>
    <div class="link-group">
      <a href="#" class="btn-link">Primary Button</a>
      <a href="#" class="btn-outline-link">Outline Button</a>
    </div>
  </div>

  <!-- Accessibility Focus -->
  <div class="section">
    <h2>Focus State (Accessibility)</h2>
    <span class="label">:focus-visible { outline: 3px solid } </span>
    <p style="margin-bottom: 15px; color: #64748b;">
      Tab to this link to see the focus ring. Use <code>:focus-visible</code> only for the keyboard, not for mouse clicks.
    </p>
    <div class="link-examples">
      <a href="#" class="accessible-link">Tab here to see the focus ring</a>
      <a href="#" class="accessible-link">Second accessible link</a>
    </div>
  </div>

  <!-- Navigation Links -->
  <div class="section">
    <h2>Navigation Links</h2>
    <span class="label">Flexbox + active state</span>
    <nav class="nav-demo">
      <a href="#">Home</a>
      <a href="#" class="active">Products</a>
      <a href="#">Tentang</a>
      <a href="#">Blog</a>
      <a href="#">Kontak</a>
    </nav>
  </div>

  <!-- Link Group -->
  <div class="section">
    <h2>Link Group</h2>
    <span class="label">Flexbox wrap + hover background</span>
    <div class="link-group">
      <a href="#" class="badge-link">All <span class="count">124</span></a>
      <a href="#" class="badge-link">Active <span class="count">89</span></a>
      <a href="#" class="badge-link">Draft <span class="count">23</span></a>
      <a href="#" class="badge-link">Arsip <span class="count">12</span></a>
    </div>
  </div>

  <!-- Breadcrumb -->
  <div class="section">
    <h2>Breadcrumb Navigation</h2>
    <span class="label">Flexbox + separator + current state</span>
    <nav>
      <ol class="breadcrumb">
        <li><a href="#">Home</a></li>
        <li class="separator">/</li>
        <li><a href="#">Products</a></li>
        <li class="separator">/</li>
        <li><a href="#">Elektronik</a></li>
        <li class="separator">/</li>
        <li class="current">Laptop ASUS ROG</li>
      </ol>
    </nav>
  </div>

  <!-- Icon Links -->
  <div class="section">
    <h2>Icon Links</h2>
    <span class="label">Inline-flex + ::after arrow</span>
    <div class="link-examples">
      <a href="#" class="icon-link">Read More</a>
      <a href="#"="icon-link icon-link-back">Back</a>
      <a href="#" class="icon-link">View All Products</a>
    </div>
  </div>

  <!-- Footer Links -->
  <div class="section" style="background: transparent; padding: 0; box-shadow: none;">
    <h2 style="color: #1a1a2e;">Footer Links</h2>
    <span class="label">Grid layout + hover translateX</span>
    <div class="footer-links">
      <div>
        <h4>Products</h4>
        <ul>
          <li><a href="#">Feature</a></li>
          <li><a href="#">Price</a></li>
          <li><a href="#">Integrasi</a></li>
          <li><a href="#">API</a></li>
        </ul>
      </div>
      <div>
        <h4>Perusahaan</h4>
        <ul>
          <li><a href="#">Tentang Kami</a></li>
          <li><a href="#">Karir</a></li>
          <li><a href="#">Blog</a></li>
          <li><a href="#">Press</a></li>
        </ul>
      </div>
      <div>
        <h4>Dukungan</h4>
        <ul>
          <li><a href="#">Help Center</a></li>
          <li><a href="#">Kontak</a></li>
          <li><a href="#">Status</a></li>
          <li><a href="#">Community</a</li>
        </ul>
      </div>
      <div>
        <h4>Legal</h4>
        <ul>
          <li><a href="#">Privacy Policy</a></li>
          <li><a href="#">Terms of Service</a></li>
          <li><a href="#">Cookie Policy</a></li>
        </ul>
      </div>
    </div>
  </div>
</body>
</html>

Code Explanation

LVHA Order

The correct pseudo-class order for links:

a:link    { color: blue; }    /* L - Link: not visited yet */
a:visited { color: purple; }  /* V - Visited: already visited */
a:hover   { color: red; }     /* H - Hover: mouse over it */
a:active  { color: orange; }  /* A - Active: while being clicked */

Why LVHA? CSS uses the cascade. If :hover is written before :visited, then :visited will override :hover for links that have already been visited.

/* Remove underline */
a { text-decoration: none; }

/* Add underline only on hover */
a:hover { text-decoration: underline; }

/* Thin, modern-style underline */
a {
  text-decoration: none;
  background-image: linear-gradient(currentColor, currentColor);
  background-size: 0% 2px;
  background-position: 0 100%;
  background-repeat: no-repeat;
  transition: background-size 0.3s;
}
a:hover { background-size: 100% 2px; }
/* Link card style */
a.card-link {
  display: block;
  padding: 20px;
  background: white;
  border-radius: 8px;
  text-decoration: none;
  color: inherit;
  transition: transform 0.3s, box-shadow 0.3s;
}
a.card-link:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0,0,0,0.15);
}

/* Link gradient underline */
a.gradient-link {
  text-decoration: none;
  background: linear-gradient(90deg, #667eea, #764ba2);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

:focus for Accessibility

/* Focus ring for keyboard navigation */
a:focus-visible {
  outline: 3px solid #667eea;
  outline-offset: 2px;
}

/* Do not show the outline for mouse clicks */
a:focus:not(:focus-visible) {
  outline: none;
}

:focus-visible is only active during keyboard navigation (Tab), not on mouse click. This is a best practice for accessibility.


Everyday Use Cases

1. Navigation Menu with Dropdown Indicators

<!DOCTYPE html>
<html lang="en">
<head>
  <style>
    * { margin: 0; padding: 0; box-sizing: border-box; }

    .top-nav {
      display: flex;
      align-items: center;
      justify-content: space-between;
      background: white;
      padding: 15px 30px;
      box-shadow: 0 2px 10px rgba(0,0,0,0.08);
    }

    .nav-brand {
      font-size: 22px;
      font-weight: bold;
      color: #1a1a2e;
      text-decoration: none;
    }

    .nav-menu {
      display: flex;
      list-style: none;
      gap: 5px;
    }

    .nav-menu a {
      text-decoration: none;
      color: #475569;
      padding: 10px 18px;
      border-radius: 8px;
      font-weight: 500;
      transition: all 0.3s;
      display: flex;
      align-items: center;
      gap: 6px;
    }

    .nav-menu a:hover {
      background: #f1f5f9;
      color: #667eea;
    }

    .nav-menu a.active {
      background: #eef2ff;
      color: #667eea;
    }

    .nav-menu a.has-dropdown::after {
      content: '▾';
      font-size: 10px;
    }

    .nav-actions {
      display: flex;
      gap: 10px;
      align-items: center;
    }

    .nav-actions .link-login {
      text-decoration: none;
      color: #475569;
      font-weight: 500;
      padding: 8px 16px;
      border-radius: 6px;
      transition: background 0.3s;
    }

    .nav-actions .link-login:hover {
      background: #f1f5f9;
    }

    .nav-actions .link-signup {
      text-decoration: none;
      color: white;
      background: #667eea;
      padding: 8px 20px;
      border-radius: 6px;
      font-weight: 600;
      transition: background 0.3s;
    }

    .nav-actions .link-signup:hover {
      background: #5a67d8;
    }
  </style>
</head>
<body>
  <nav class="top-nav">
    <a href="#" class="nav-brand">SkillVersitas</a>
    <ul class="nav-menu">
      <li><a href="#">Home</a></li>
      <li><a href="#" class="active">Kursus</a></li>
      <li><a href="#" class="has-dropdown">Kategori</a></li>
      <li><a href="#">Mentor</a></li>
      <li><a href="#">Komunitas</a></li>
    </ul>
    <div class="nav-actions">
      <a href="#" class="link-login">Log In</a>
      <a href="#" class="link-signup">Sign Up Free</a>
    </div>
  </nav>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
  <style>
    * { margin: 0; padding: 0; box-sizing: border-box; }

    .related-section {
      padding: 40px 20px;
      max-width: 800px;
      margin: 0 auto;
    }

    .related-section h2 {
      margin-bottom: 25px;
      color: #1a1a2e;
    }

    .related-list {
      display: flex;
      flex-direction: column;
      gap: 15px;
    }

    .related-item {
      display: flex;
      gap: 20px;
      padding: 20px;
      background: white;
      border-radius: 12px;
      box-shadow: 0 2px 8px rgba(0,0,0,0.06);
      text-decoration: none;
      color: inherit;
      transition: all 0.3s;
      border: 2px solid transparent;
    }

    .related-item:hover {
      border-color: #667eea;
      transform: translateX(5px);
      box-shadow: 0 4px 15px rgba(102, 126, 234, 0.15);
    }

    .related-thumb {
      width: 100px;
      height: 80px;
      border-radius: 8px;
      flex-shrink: 0;
      display: flex;
      align-items: center;
      justify-content: center;
      color: white;
      font-weight: bold;
    }

    .related-thumb:nth-child(1) { background: #667eea; }

    .related-item:nth-child(1) .related-thumb { background: #667eea; }
    .related-item:nth-child(2) .related-thumb { background: #f5576c; }
    .related-item:nth-child(3) .related-thumb { background: #43e97b; }

    .related-content h3 {
      font-size: 16px;
      margin-bottom: 6px;
      color: #1e293b;
      transition: color 0.3s;
    }

    .related-item:hover .related-content h3 {
      color: #667eea;
    }

    .related-content p {
      font-size: 14px;
      color: #64748b;
      line-height: 1.5;
    }

    .related-meta {
      font-size: 12px;
      color: #94a3b8;
      margin-top: 8px;
    }

    .read-more {
      display: inline-flex;
      align-items: center;
      gap: 6px;
      color: #667eea;
      text-decoration: none;
      font-weight: 600;
      font-size: 14px;
      margin-top: 10px;
      transition: gap 0.3s;
    }

    .read-more:hover {
      gap: 10px;
    }

    .read-more::after {
      content: '→';
    }
  </style>
</head>
<body>
  <section class="related-section">
    <h2>Related Articles</h2>
    <div class="related-list">
      <a href="#" class="related-item">
        <div class="related-thumb">1</div>
        <div class="related-content">
          <h3>Understanding CSS Flexbox from the Basics</h3>
          <p>A complete guide to understanding Flexbox for beginners, with real-world case studies.</p>
          <span class="read-more">Read More</span>
        </div>
      </a>
      <a href="#" class="related-item">
        <div class="related-thumb">2</div>
        <div class="related-content">
          <h3>CSS Grid vs Flexbox: Which One to Choose?</h3>
          <p>An in-depth comparison of when to use Grid and when to use Flexbox.</p>
          <span class="read-more">Read More</span>
        </div>
      </a>
      <a href="#" class="related-item">
        <div class="related-thumb">3</div>
        <div class="related-content">
          <h3>Responsive Design Modern Without Media Queries</h3>
          <p>Techniques using minmax(), auto-fit, and the fr unit for responsive layouts.</p>
          <span class="read-more">Read More</span>
        </div>
      </a>
    </div>
  </section>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
  <style>
    * { margin: 0; padding: 0; box-sizing: border-box; }

    .social-section {
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: 20px;
      padding: 40px;
    }

    .social-links {
      display: flex;
      gap: 15px;
    }

    .social-link {
      display: flex;
      align-items: center;
      justify-content: center;
      width: 50px;
      height: 50px;
      border-radius: 50%;
      text-decoration: none;
      color: white;
      font-weight: bold;
      font-size: 18px;
      transition: all 0.3s;
      position: relative;
    }

    .social-link:hover {
      transform: translateY(-3px);
      box-shadow: 0 5px 15px rgba(0,0,0,0.2);
    }

    .social-link:focus-visible {
      outline: 3px solid #667eea;
      outline-offset: 3px;
    }

    .social-link.twitter { background: #1da1f2; }
    .social-link.github { background: #333; }
    .social-link.linkedin { background: #0a66c2; }
    .social-link.youtube { background: #ff0000; }

    .social-link.github::before { content: 'GH'; }
    .social-link.twitter::before { content: 'TW'; }
    .social-link.linkedin::before { content: 'IN'; }
    .social-link.youtube::before { content: 'YT'; }

    .share-links {
      display: flex;
      gap: 10px;
    }

    .share-link {
      display: inline-flex;
      align-items: center;
      gap: 6px;
      padding: 8px 16px;
      border-radius: 20px;
      text-decoration: none;
      font-size: 13px;
      font-weight: 600;
      transition: all 0.3s;
    }

    .share-link.twitter {
      background: #e8f5fe;
      color: #1da1f2;
    }

    .share-link.twitter:hover {
      background: #1da1f2;
      color: white;
    }

    .share-link.facebook {
      background: #e7f3ff;
      color: #1877f2;
    }

    .share-link.facebook:hover {
      background: #1877f2;
      color: white;
    }

    .share-link.whatsapp {
      background: #e6faf0;
      color: #25d366;
    }

    .share-link.whatsapp:hover {
      background: #25d366;
      color: white;
    }
  </style>
</head>
<body>
  <div class="social-section">
    <h2>Ikuti Kami</h2>
    <div class="social-links">
      <a href="#" class="social-link github" aria-label="GitHub"></a>
      <a href="#" class="social-link twitter" aria-label="Twitter"></a>
      <a href="#" class="social-link linkedin" aria-label="LinkedIn"></a>
      <a href="#" class="social-link youtube" aria-label="YouTube"></a>
    </div>

    <h3 style="margin-top: 20px; font-size: 16px; color: #64748b;">Share This Article</h3>
    <div class="share-links">
      <a href="#" class="share-link twitter">🐦 Twitter</a>
      <a href="#" class="share-link facebook">📘 Facebook</a>
      <a href="#" class="share-link whatsapp">💬 WhatsApp</a>
    </div>
  </div>
</body>
</html>

Conclusion

CSS Links lets you create interactive and accessible links. Key points:

  1. LVHA order — :link, :visited, :hover, :active — the correct order is crucial
  2. :focus-visible — Accessibility best practice for keyboard navigation
  3. text-decoration: none — Remove the default underline and create a custom underline with a pseudo-element
  4. Transform & Transition — Smooth hover effects on links
  5. Semantic HTML — Use <nav> for navigation and <a> for all links

Always test your links with the keyboard (Tab) to ensure accessibility. A focus ring must not be removed without providing a visual alternative.