WeTeach Design System

Comprehensive guide for buttons, layout patterns, cards, badges, empty states, and more.

Part 1: Buttons

Primary Buttons

Use for: Main call-to-action, primary user actions, form submissions, create/add actions

Examples: "Tạo yêu cầu", "Đăng ký", "Lưu", "Gửi đơn", "Xác nhận"

Standard Primary
Primary Sizes
Primary with Icons
Code Example
<button type="button" class="btn btn-primary">Tạo yêu cầu dạy học</button>
<!-- Rounded pill CTA -->
<a href="#" class="btn btn-success btn-sm rounded-pill px-3">
    <i class="bi bi-plus-lg me-1"></i>Tạo Lớp Học Mới
</a>

Success Buttons

Use for: Confirmation actions, approve/accept actions, positive outcomes, create actions

Examples: "Chấp nhận", "Phê duyệt", "Tạo Lớp Học Mới", "Hoàn thành"

Danger Buttons

Use for: Destructive actions, delete/remove, reject/decline

Secondary / Warning / Info Buttons

Secondary (Cancel, Back)
Warning (Caution, Pause)
Info (View, Learn more)
Light (Filter reset, subtle actions)

Outline Buttons

Use for: Secondary actions, less visual weight, mobile filter toggles

Soft Buttons

Use for: Subtle actions, tags, filters, badges with interaction, header nav

<button class="btn btn-primary-soft">Primary Soft</button>

Icon-Only Buttons

Use for: Space-constrained areas. Always add aria-label.

Button Groups, Blocks & Disabled State

Button Group
Block Buttons
Disabled State

Part 2: Layout Patterns

Hero Section

Use for: Top of listing pages. Contains badge, title, subtitle, and search bar.
Gradient: linear-gradient(135deg, #2888d2 0%, #f3c935 100%)
Decorative elements: ::before and ::after pseudo-elements with large semi-transparent circles.

Nền tảng học tập WeTeach

Trang Mẫu

Mô tả ngắn gọn về nội dung trang hiển thị tại đây

Code Structure
<section class="hero-classes py-5">
    <div class="container position-relative" style="z-index: 1;">
        <div class="row justify-content-center">
            <div class="col-lg-8 text-center">
                <span class="badge bg-white bg-opacity-25 text-white px-3 py-2 rounded-pill mb-3">
                    <i class="bi bi-mortarboard me-1"></i> Badge Text
                </span>
                <h1 class="text-white display-5 fw-bold mb-3">Page Title</h1>
                <p class="text-white text-opacity-90 fs-5 mb-4">Subtitle</p>
                <!-- Search bar -->
                <form class="d-flex justify-content-center">
                    <div class="input-group" style="max-width: 560px;">
                        <input class="form-control form-control-lg border-0 shadow" type="search" placeholder="...">
                        <button type="submit" class="btn btn-dark btn-lg px-4">
                            <i class="bi bi-search"></i>
                        </button>
                    </div>
                </form>
            </div>
        </div>
    </div>
</section>
Required CSS
.hero-classes {
    background: linear-gradient(135deg, #2888d2 0%, #f3c935 100%);
    position: relative;
    overflow: hidden;
}
.hero-classes::before {
    content: '';
    position: absolute;
    top: -50%; right: -20%;
    width: 600px; height: 600px;
    border-radius: 50%;
    background: rgba(255,255,255,0.05);
}
.hero-classes::after {
    content: '';
    position: absolute;
    bottom: -30%; left: -10%;
    width: 400px; height: 400px;
    border-radius: 50%;
    background: rgba(255,255,255,0.05);
}

Main + Sidebar Layout

Use for: All listing pages (classes, posts, teachers). Main content area with filter sidebar that collapses to offcanvas on mobile.

Main Content
col-lg-8 col-xl-9
Toolbar, Card Grid, Pagination
Sidebar
col-lg-4 col-xl-3
Filter Cards (offcanvas on mobile)
<section class="pt-4 pb-5">
    <div class="container">
        <div class="row">
            <div class="col-lg-8 col-xl-9">
                <!-- Toolbar, Grid, Pagination -->
            </div>
            <div class="col-lg-4 col-xl-3">
                <div class="offcanvas-lg offcanvas-end" id="offcanvasSidebar">
                    <div class="offcanvas-header bg-light">...</div>
                    <div class="offcanvas-body p-3 p-lg-0">
                        <form method="GET">
                            <!-- Filter cards here -->
                        </form>
                    </div>
                </div>
            </div>
        </div>
    </div>
</section>

Toolbar Pattern

Use for: Sort dropdown + result count + mobile filter toggle. Always appears above the card grid.

Hiển thị 1-10 / 50

<div class="d-flex flex-wrap justify-content-between align-items-center gap-3 mb-4">
    <form method="GET" class="d-inline-flex align-items-center">
        <label class="me-2 small fw-semibold text-nowrap">
            <i class="bi bi-sort-down me-1"></i>Sắp xếp:
        </label>
        <select class="form-select form-select-sm" name="sort" style="width: auto;" onchange="this.form.submit()">
            <option value="newest">Mới nhất</option>
            ...
        </select>
    </form>
    <div class="d-flex align-items-center gap-3">
        <button class="btn btn-outline-primary btn-sm d-lg-none" data-bs-toggle="offcanvas" data-bs-target="#offcanvasSidebar">
            <i class="bi bi-funnel me-1"></i>Bộ lọc
        </button>
        <p class="mb-0 text-body-secondary small">
            Hiển thị <strong>1-10</strong> / <strong>50</strong>
        </p>
    </div>
</div>

CTA Gradient Section

Use for: Bottom of listing pages. Encourages user action (signup, create, etc.).
Buttons: btn-white (primary) and btn-hero-secondary (glass effect).

Bạn là giáo viên? Tạo lớp học ngay!

Chia sẻ kiến thức của bạn với hàng ngàn học viên. Đăng ký miễn phí!

Required CSS
.cta-gradient {
    background: linear-gradient(135deg, #2888d2 0%, #f3c935 100%);
    position: relative; overflow: hidden; border-radius: 8px;
}
.cta-gradient::before {
    content: '';
    position: absolute; top: -40%; right: -15%;
    width: 400px; height: 400px; border-radius: 50%;
    background: rgba(255,255,255,0.06);
}
.btn-hero-secondary {
    background: rgba(255,255,255, 0.15);
    color: #fff;
    border: 2px solid rgba(255,255,255, 0.5);
    backdrop-filter: blur(4px);
}
.btn-hero-secondary:hover {
    background: rgba(255,255,255, 0.3);
    border-color: rgba(255,255,255, 0.8);
}

Part 3: Components

Item Cards

Use for: Class cards, course cards, post cards in listing grids.
Grid: col-sm-6 col-xl-4 (3 columns on XL, 2 on SM)
Key CSS: border-radius: 16px, hover translateY(-4px), shadow-sm

16:9 Image
Giáo viên tự do
550.000₫
Toán học Vật lý
Tên khóa học / lớp học hiển thị tại đây

Mô tả ngắn gọn về nội dung khóa học hiển thị ở đây...

01/03/2026 12 buổi
16:9 Image
Trung tâm
Miễn phí
Deep Learning
Tên khóa học trung tâm

Mô tả ngắn gọn khóa học trung tâm...

20 buổi 150 học viên
Required CSS
.class-item-card { /* or any item card class */
    border: none;
    border-radius: 8px;
    transition: transform 0.3s ease, box-shadow 0.3s ease;
    cursor: pointer;
}
.class-item-card:hover {
    transform: translateY(-4px);
    box-shadow: 0 0.5rem 1.5rem rgba(0,0,0,0.1) !important;
}
.type-badge {
    padding: 6px 14px;
    border-radius: 0 0 8px 0;
    font-size: 0.78rem;
    font-weight: 600;
}
.text-truncate-2 {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

Filter Sidebar Cards

Use for: Each filter group in the sidebar (subjects, location, fee, etc.).
Structure: Icon + label header, then filter control.

Môn Học
Địa Điểm
Học Phí
Action Buttons (bottom of filter form)
Xóa bộ lọc
.filter-sidebar-card {
    border: none;
    border-radius: 8px;
    transition: box-shadow 0.3s ease;
}
.filter-sidebar-card:hover {
    box-shadow: 0 0.5rem 1.5rem rgba(0,0,0,0.08) !important;
}

Badges & Tags

Type Badges (card image overlay, top-left)

Use: Identify card type. Uses .type-badge class.

Giáo viên tự do Trung tâm
Subject Badges (card body)

Use: Show subjects using bg-{color} bg-opacity-10 text-{color}

Toán học Vật lý +2
Deep Learning Python
Fee Badges (card image overlay, bottom-right)
550.000₫ Miễn phí
Status Badges
Online Chờ duyệt Hoạt động
Hero / Page Badge
Nền tảng học tập WeTeach

Empty States

Use for: When search/filter returns no results. Centered icon + message + action buttons.

Không tìm thấy kết quả

Chúng tôi không thể tìm thấy lớp học hoặc khóa học nào phù hợp với tiêu chí của bạn. Hãy thử thay đổi bộ lọc hoặc từ khóa tìm kiếm.

<div class="card border-0 shadow-sm rounded-4 p-5 text-center">
    <div class="mx-auto mb-3 empty-state-icon bg-warning bg-opacity-10 text-warning">
        <i class="bi bi-journal-x"></i>
    </div>
    <h5 class="fw-semibold mb-2">Không tìm thấy kết quả</h5>
    <p class="text-body-secondary mb-3">Message here...</p>
    <div class="d-flex justify-content-center gap-2">
        <a href="#" class="btn btn-primary">Action 1</a>
        <a href="#" class="btn btn-success">Action 2</a>
    </div>
</div>

/* Required CSS */
.empty-state-icon {
    width: 80px; height: 80px;
    display: flex; align-items: center; justify-content: center;
    border-radius: 50%; font-size: 2rem;
}

Radio Pill Filters

Use for: Mutually exclusive filter options (location type: all/online/offline).

<input type="radio" class="btn-check" name="location" value="" id="location-all" checked>
<label class="btn btn-outline-primary btn-sm rounded-pill" for="location-all">Tất cả</label>

<input type="radio" class="btn-check" name="location" value="online" id="location-online">
<label class="btn btn-outline-primary btn-sm rounded-pill" for="location-online">
    <i class="bi bi-wifi me-1"></i>Online
</label>

Part 4: Guidelines & Best Practices

Usage Guidelines

Do's
  • Use clear, action-oriented labels (e.g., "Tạo yêu cầu" not "OK")
  • Limit to one primary action per screen/section
  • Use rounded-pill for create/CTA buttons
  • Use border-radius: 16px for all cards
  • Use the Hero + Main/Sidebar + CTA layout for listing pages
  • Use shadow-sm for cards, shadow for modals
  • Use Bootstrap Icons (bi-*) everywhere — NOT FontAwesome
  • Use text-body-secondary — NOT text-muted
  • Preserve all filter params when submitting sort/search/pagination
  • Use offcanvas sidebar for mobile filter UI
  • Show loading states for async actions
Don'ts
  • Don't use FontAwesome icons (fas fa-*)
  • Don't use text-muted — use text-body-secondary
  • Don't use bg-dark for hero banners — use the gradient
  • Don't use multiple primary buttons in the same context
  • Don't use red/danger buttons for non-destructive actions
  • Don't use vague labels like "Click here" or "Submit"
  • Don't use inline styles for border-radius on cards (use CSS class)
  • Don't put search in both hero AND filter sidebar (hero only)
  • Don't use btn-success-soft for create CTAs — use btn-success rounded-pill
  • Don't forget to show empty states when no results

Action Priority Hierarchy
Priority Button Style Usage Example
Critical Destructive, irreversible actions Delete account, Remove post
High Main call-to-action Create, Submit, Save, Apply Filter
Medium-High Create/add CTAs, confirmations Tạo Lớp Học Mới, Chấp nhận
Medium Secondary actions Edit, View, Download, Filter toggle
Low / Tertiary, reset actions Clear filters, Learn more, Terms

Standard Page Structure
Section Purpose Key Classes
Hero Page title, subtitle, search .hero-{page} py-5, gradient, decorative circles
Toolbar Sort, result count, mobile filter toggle d-flex flex-wrap justify-content-between
Create CTA Role-aware create button btn btn-success btn-sm rounded-pill px-3
Card Grid Item listing row g-4, col-sm-6 col-xl-4
Empty State No results message card border-0 shadow-sm rounded-4 p-5 text-center
Pagination Page navigation pagination pagination-primary-soft
Sidebar Filter cards offcanvas-lg offcanvas-end, .filter-sidebar-card
CTA Section Bottom call-to-action .cta-gradient, btn-white, btn-hero-secondary

Accessibility Considerations

  • Semantic HTML: Use <button> for actions, <a> for navigation
  • aria-label for icon-only buttons: <button class="btn btn-primary btn-icon" aria-label="Chỉnh sửa"><i class="bi bi-pencil"></i></button>
  • aria-label for pagination: <nav aria-label="điều hướng">
  • Disabled state: Use both disabled attribute and aria-disabled="true"
  • Focus indicators: Ensure visible focus states for keyboard navigation
  • Color contrast: Text meets WCAG AA standards (4.5:1)
  • Touch targets: Minimum 44x44px for mobile
Đang tải...

Đang tải...