Skip to content

Building UI Components — Buttons, Cards & Form Design Patterns

Site Console Site Console
4 min read Updated Oct 19, 2025 Frontend Design 0 comments

ntroduction

UI components are the building blocks of every frontend design system.
Instead of rewriting styles for each button or form, we build modular, reusable, consistent components that work everywhere.

In this post, you’ll learn how to:

  • Design reusable buttons, cards, and form elements

  • Apply BEM structure, CSS variables, and utility classes

  • Use responsive and state-aware styling

  • Create components that are easy to extend and theme


1. Buttons — Small Component, Big Impact

Buttons communicate action. A consistent button system keeps your UI unified and recognizable.

1.1 HTML Structure (BEM Convention)

<button class="btn btn--primary">Primary</button>
<button class="btn btn--secondary">Secondary</button>
<button class="btn btn--outline">Outline</button>

1.2 CSS (with Variables + States)

:root {
  --btn-radius: 6px;
  --btn-padding: 0.75rem 1.5rem;
  --btn-font: 'Inter', sans-serif;
  --btn-primary-bg: #0077ff;
  --btn-secondary-bg: #444;
  --btn-outline-border: #0077ff;
}

/* Base button */
.btn {
  font-family: var(--btn-font);
  padding: var(--btn-padding);
  border-radius: var(--btn-radius);
  border: none;
  cursor: pointer;
  font-weight: 600;
  transition: background 0.3s ease, transform 0.2s ease;
}

/* Variants */
.btn--primary {
  background: var(--btn-primary-bg);
  color: #fff;
}

.btn--secondary {
  background: var(--btn-secondary-bg);
  color: #fff;
}

.btn--outline {
  background: transparent;
  color: var(--btn-outline-border);
  border: 2px solid var(--btn-outline-border);
}

/* States */
.btn:hover {
  transform: translateY(-2px);
}

.btn:active {
  transform: translateY(0);
  opacity: 0.9;
}

.btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

Best Practices:

  • Use variables for global theming

  • Avoid inline colors or hardcoded values

  • Use consistent padding & border radius for visual harmony


2. Cards — Reusable Content Blocks

Cards display grouped information (titles, descriptions, actions).
They must be flexible and responsive, yet maintain structure.

2.1 HTML Example

<article class="card card--featured">
  <img src="project.jpg" alt="Project thumbnail" class="card__img" />
  <div class="card__content">
    <h3 class="card__title">Project Name</h3>
    <p class="card__desc">A short description of the project goes here.</p>
    <a href="#" class="btn btn--primary card__btn">View Project</a>
  </div>
</article>

2.2 CSS (Grid + Responsive)

.card {
  background: #fff;
  border-radius: 10px;
  overflow: hidden;
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
  transition: transform 0.3s ease;
  display: grid;
  grid-template-columns: 1fr;
}

.card:hover {
  transform: translateY(-4px);
}

.card__img {
  width: 100%;
  display: block;
}

.card__content {
  padding: 1rem;
}

.card__title {
  font-size: 1.25rem;
  margin-bottom: 0.5rem;
}

.card__desc {
  color: #555;
  margin-bottom: 1rem;
}

@media (min-width: 768px) {
  .card {
    grid-template-columns: 1fr 1.5fr;
  }
}

Features:

  • Grid layout for flexible image-text structure

  • Smooth hover elevation

  • Works well across screen sizes


3. Form Design Patterns

Forms are critical for UX — contact forms, logins, signups, etc.
They should be consistent, accessible, and visually aligned with your design system.

3.1 HTML Example

<form class="form">
  <label class="form__label" for="name">Name</label>
  <input class="form__input" type="text" id="name" placeholder="Enter your name" required>

  <label class="form__label" for="email">Email</label>
  <input class="form__input" type="email" id="email" placeholder="Enter your email" required>

  <button class="btn btn--primary form__btn">Submit</button>
</form>

3.2 CSS

.form {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  max-width: 400px;
  margin: auto;
  background: #fff;
  padding: 2rem;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}

.form__label {
  font-weight: 600;
  font-size: 0.95rem;
}

.form__input {
  padding: 0.75rem;
  border: 1px solid #ccc;
  border-radius: 6px;
  font-size: 1rem;
  transition: border 0.3s ease, box-shadow 0.3s ease;
}

.form__input:focus {
  border-color: #0077ff;
  box-shadow: 0 0 0 2px rgba(0,119,255,0.2);
  outline: none;
}

Accessibility Tips:

  • Always pair <label> with for and input id

  • Use :focus states for keyboard users

  • Provide descriptive placeholders and error messages


4. Component Variants with Modifiers

Modifiers (--large, --danger, etc.) create reusable variants.

.btn--large {
  padding: 1rem 2rem;
  font-size: 1.1rem;
}

.btn--danger {
  background: #e63946;
}

.card--compact {
  box-shadow: none;
  border: 1px solid #eee;
}

5. Responsive & Theming Adaptations

You can apply global or container-based themes using custom properties.

:root {
  --card-bg: #fff;
  --card-text: #222;
}

[data-theme="dark"] {
  --card-bg: #222;
  --card-text: #eee;
}

.card {
  background: var(--card-bg);
  color: var(--card-text);
}

Result:
Dark mode-ready components without rewriting CSS.


6. Component Library Structure

Organize reusable components clearly:

/components
  _buttons.scss
  _cards.scss
  _forms.scss
  _modals.scss

Each file defines BEM components + utilities.
You can compile them together via Sass, PostCSS, or Tailwind config.


✅ Summary & What’s Next

You’ve learned:

  • How to structure and style buttons, cards, and forms

  • How to use BEM and utility classes together

  • How to theme and scale components with CSS Variables

  • How to ensure accessibility and responsive behavior

Up next, you’ll learn how to make your UI interactive and dynamic using animations, transitions, and microinteractions — techniques that bring personality and life to your frontend.

Related

Leave a comment

Sign in to leave a comment.

Comments