DEV Community

Cover image for Stop Building Multiple Components — Use Class-Based Variants Instead
Pawar Shivam
Pawar Shivam

Posted on

Stop Building Multiple Components — Use Class-Based Variants Instead

Learn how to build one reusable timeline component and control multiple UI variations using only CSS classes.

=> We Keep Rebuilding the Same Component 😐

Timeline for roles
Timeline for progress
Timeline for steps

👉 Every time → new component


=> The Real Problem

It’s NOT UI complexity

👉 It’s how we think about components


=> Common Developer Mistakes

• duplicate HTML for similar layouts
• add unnecessary JS for switching UI
• create multiple CSS files

👉 More code, more bugs


=> Real Example (From My Project)

I built two timeline versions:

👉 Version 1 (Roles)

👉 Version 2 (Progress)


=> They Look Different… But 👀

👉 Same structure
👉 Same HTML
👉 Same logic


=> The Fix: One Reusable Component 🔥


=> 1. Single HTML Structure

<div class="container-timeline">
  <div class="timeline">
    <div class="timeline-row active">
      <div class="dot"></div>
      <div class="hline"></div>
      <div class="num"></div>
      <div class="card-sec">Content</div>
    </div>
  </div>
</div>
Enter fullscreen mode Exit fullscreen mode

👉 No duplication
👉 Clean structure


=> 2. Layout with Pure CSS

.timeline-row:nth-child(odd) .card-sec {
  left: 60%;
}

.timeline-row:nth-child(even) .card-sec {
  right: 60%;
}
Enter fullscreen mode Exit fullscreen mode

👉 No JS needed
👉 Fully responsive logic


=> 3. Auto Numbering (Zero JS 😎)

.timeline {
  counter-reset: step;
}

.timeline-row {
  counter-increment: step;
}

.num::before {
  content: counter(step, decimal-leading-zero);
}
Enter fullscreen mode Exit fullscreen mode

👉 No props
👉 No manual numbering


=> 4. Variant Switch (The Real Power)

Just change ONE class:

<div class="container-timeline"></div>
Enter fullscreen mode Exit fullscreen mode

vs

<div class="container-timeline container-timeline-progress"></div>
Enter fullscreen mode Exit fullscreen mode

👉 That’s it 😳


=> What Changes Automatically?

With .container-timeline-progress:

• progress line activates
• colors change (active/pending)
• completion state appears

.container-timeline-progress .timeline::before {
  background: linear-gradient(...);
}
Enter fullscreen mode Exit fullscreen mode

=> Hidden Dev Insight 🧠

Most UI differences are:

👉 styling differences
👉 state differences

NOT structure


=> So What Should Handle It?

👉 CSS (not JS)


=> Real UI Architecture Rule

Design like this:

.timeline { }              /* base */
.container-timeline-progress { }  /* modifier */
Enter fullscreen mode Exit fullscreen mode

👉 Base = structure
👉 Modifier = variation


=> Why This Matters

• reusable components
• less code
• easier maintenance
• scalable design system


=> Final Thought

Stop building new components for small changes…

👉 Start designing flexible ones 🚀


=> What Do You Think?

Do you create new components for variations — or reuse with classes?

Top comments (0)