Bài 17: Mini Project – Xây dựng trang web đơn giản

Bạn đã học hết các kiến thức HTML & CSS cơ bản. Bây giờ đến lúc áp dụng thực tế — xây dựng một trang web thực sự hoạt động!

Bài này sẽ hướng dẫn bạn từng bước xây dựng một trang Portfolio đơn giản nhưng chuyên nghiệp. Bạn sẽ áp dụng tất cả kiến thức đã học: HTML semantic, CSS responsive, mobile-first, animation, typography… Sau khi hoàn thành, bạn sẽ có một trang web thực sự có thể chia sẻ!

Yêu cầu dự án

Trang Portfolio cá nhân với:

  • ✅ Header/Navigation (sticky hoặc fixed)
  • ✅ Hero section (banner đẹp)
  • ✅ About section (giới thiệu)
  • ✅ Projects/Works section (hiển thị dự án)
  • ✅ Contact section (form liên hệ hoặc thông tin)
  • ✅ Footer
  • ✅ Fully responsive (mobile-first)
  • ✅ Smooth animations/transitions
  • ✅ Professional typography

Bước 1: HTML (Semantic & Clean)

<!DOCTYPE html>
<html lang="vi">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Nguyễn Văn A - Portfolio</title>
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  <link href="https://fonts.googleapis.com/css2?family=Playfair+Display:wght@700&family=Lato:wght@400;700&display=swap" rel="stylesheet">
  <link rel="stylesheet" href="styles.css">
</head>
<body>

  <!-- ========== HEADER ========== -->
  <header class="header">
    <div class="header-content">
      <h1 class="logo">NVA</h1>
      <nav class="nav">
        <a href="#about">Về tôi</a>
        <a href="#projects">Dự án</a>
        <a href="#contact">Liên hệ</a>
      </nav>
    </div>
  </header>

  <!-- ========== HERO SECTION ========== -->
  <section class="hero">
    <div class="hero-overlay"></div>
    <div class="hero-content">
      <h1>Xin chào, tôi là Nguyễn Văn A</h1>
      <p class="tagline">Lập trình viên Front-end & Web Designer</p>
      <a href="#projects" class="cta-button">Xem dự án của tôi</a>
    </div>
  </section>

  <!-- ========== ABOUT SECTION ========== -->
  <section id="about" class="about">
    <div class="container">
      <h2>Về tôi</h2>
      <p>
        Tôi là một lập trình viên web đam mê với 3 năm kinh nghiệm. 
        Tôi chuyên về HTML, CSS, JavaScript, và React. 
        Tôi yêu thích tạo những trang web đẹp, responsive, và user-friendly.
      </p>
      <p>
        Kỹ năng của tôi bao gồm: HTML5, CSS3, JavaScript, React, Responsive Design, 
        Git, Figma, và WordPress.
      </p>
      <h3>Kỹ năng</h3>
      <ul class="skills">
        <li>HTML5 & CSS3</li>
        <li>JavaScript</li>
        <li>React</li>
        <li>Responsive Design</li>
        <li>Git & GitHub</li>
        <li>Figma</li>
      </ul>
    </div>
  </section>

  <!-- ========== PROJECTS SECTION ========== -->
  <section id="projects" class="projects">
    <div class="container">
      <h2>Dự án của tôi</h2>
      
      <div class="projects-grid">
        <!-- Project 1 -->
        <article class="project-card">
          <div class="project-image" style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);"></div>
          <div class="project-content">
            <h3>Website Blog</h3>
            <p>Một trang blog đẹp với responsive design, smooth animation, và user-friendly interface.</p>
            <div class="project-tags">
              <span class="tag">HTML</span>
              <span class="tag">CSS</span>
              <span class="tag">JavaScript</span>
            </div>
            <a href="#" class="project-link">Xem dự án →</a>
          </div>
        </article>

        <!-- Project 2 -->
        <article class="project-card">
          <div class="project-image" style="background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);"></div>
          <div class="project-content">
            <h3>E-commerce Store</h3>
            <p>Cửa hàng trực tuyến với product gallery, shopping cart, và checkout flow.</p>
            <div class="project-tags">
              <span class="tag">React</span>
              <span class="tag">CSS</span>
              <span class="tag">API</span>
            </div>
            <a href="#" class="project-link">Xem dự án →</a>
          </div>
        </article>

        <!-- Project 3 -->
        <article class="project-card">
          <div class="project-image" style="background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);"></div>
          <div class="project-content">
            <h3>Task Management App</h3>
            <p>Ứng dụng quản lý công việc với drag-and-drop, local storage, và responsive design.</p>
            <div class="project-tags">
              <span class="tag">JavaScript</span>
              <span class="tag">CSS</span>
              <span class="tag">Storage</span>
            </div>
            <a href="#" class="project-link">Xem dự án →</a>
          </div>
        </article>
      </div>
    </div>
  </section>

  <!-- ========== CONTACT SECTION ========== -->
  <section id="contact" class="contact">
    <div class="container">
      <h2>Liên hệ với tôi</h2>
      <p class="contact-intro">Tôi luôn vui lòng nghe những ý tưởng mới. Hãy liên hệ với tôi!</p>
      
      <div class="contact-grid">
        <!-- Contact Info -->
        <div class="contact-info">
          <h3>📬 Thông tin liên hệ</h3>
          <ul>
            <li><strong>Email:</strong> nguyenvana@email.com</li>
            <li><strong>Phone:</strong> +84 (0) 123 456 789</li>
            <li><strong>Location:</strong> Hà Nội, Việt Nam</li>
          </ul>
          <h3>🔗 Mạng xã hội</h3>
          <div class="social-links">
            <a href="#" class="social-link">GitHub</a>
            <a href="#" class="social-link">LinkedIn</a>
            <a href="#" class="social-link">Twitter</a>
          </div>
        </div>

        <!-- Contact Form -->
        <form class="contact-form">
          <div class="form-group">
            <label for="name">Tên</label>
            <input type="text" id="name" name="name" required>
          </div>
          <div class="form-group">
            <label for="email">Email</label>
            <input type="email" id="email" name="email" required>
          </div>
          <div class="form-group">
            <label for="message">Lời nhắn</label>
            <textarea id="message" name="message" rows="5" required></textarea>
          </div>
          <button type="submit" class="submit-btn">Gửi</button>
        </form>
      </div>
    </div>
  </section>

  <!-- ========== FOOTER ========== -->
  <footer class="footer">
    <p>© 2024 Nguyễn Văn A. Tất cả quyền được bảo lưu.</p>
    <p>Thiết kế với ❤️ bằng HTML, CSS, và JavaScript</p>
  </footer>

</body>
</html>

Bước 2: CSS (Mobile First & Responsive)

/* ========== RESET & BASE ========== */

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html {
  font-size: 16px;
  scroll-behavior: smooth;
}

body {
  font-family: 'Lato', sans-serif;
  line-height: 1.6;
  color: #333;
  background-color: #f9f9f9;
}

.container {
  width: 100%;
  padding: 0 20px;
  margin: 0 auto;
}

/* ========== HEADER (MOBILE) ========== */

.header {
  background-color: #2c3e50;
  color: white;
  padding: 20px 0;
  position: sticky;
  top: 0;
  z-index: 100;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.header-content {
  display: flex;
  justify-content: space-between;
  align-items: center;
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 20px;
}

.logo {
  font-family: 'Playfair Display', serif;
  font-size: 28px;
  font-weight: 700;
}

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

.nav a {
  color: white;
  text-decoration: none;
  font-weight: 500;
  padding: 8px 15px;
  border-radius: 5px;
  transition: background-color 0.3s;
}

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

/* ========== HERO SECTION (MOBILE) ========== */

.hero {
  position: relative;
  height: 400px;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  color: white;
  overflow: hidden;
}

.hero-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.2);
}

.hero-content {
  position: relative;
  z-index: 10;
  padding: 20px;
}

.hero h1 {
  font-family: 'Playfair Display', serif;
  font-size: 32px;
  margin-bottom: 10px;
  text-shadow: 2px 2px 8px rgba(0, 0, 0, 0.3);
}

.hero .tagline {
  font-size: 18px;
  margin-bottom: 25px;
  opacity: 0.95;
}

.cta-button {
  display: inline-block;
  padding: 12px 30px;
  background-color: white;
  color: #667eea;
  text-decoration: none;
  border-radius: 5px;
  font-weight: bold;
  transition: transform 0.3s, box-shadow 0.3s;
}

.cta-button:hover {
  transform: translateY(-3px);
  box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
}

/* ========== ABOUT SECTION (MOBILE) ========== */

.about {
  padding: 40px 0;
  background-color: white;
}

.about .container {
  max-width: 100%;
}

.about h2 {
  font-family: 'Playfair Display', serif;
  font-size: 28px;
  color: #2c3e50;
  margin-bottom: 25px;
  text-align: center;
}

.about p {
  font-size: 16px;
  line-height: 1.8;
  color: #555;
  margin-bottom: 20px;
  text-align: justify;
}

.about h3 {
  font-size: 20px;
  color: #2c3e50;
  margin-top: 30px;
  margin-bottom: 15px;
}

.skills {
  list-style: none;
  display: grid;
  grid-template-columns: 1fr;
  gap: 12px;
}

.skills li {
  background-color: #f0f0f0;
  padding: 12px 15px;
  border-left: 4px solid #667eea;
  border-radius: 4px;
}

/* ========== PROJECTS SECTION (MOBILE) ========== */

.projects {
  padding: 40px 0;
  background-color: #f9f9f9;
}

.projects h2 {
  font-family: 'Playfair Display', serif;
  font-size: 28px;
  color: #2c3e50;
  margin-bottom: 40px;
  text-align: center;
}

.projects-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 30px;
}

.project-card {
  background: white;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  transition: all 0.3s ease;
}

.project-card:hover {
  box-shadow: 0 8px 16px rgba(0, 0, 0, 0.15);
  transform: translateY(-5px);
}

.project-image {
  width: 100%;
  height: 250px;
  background-size: cover;
  background-position: center;
}

.project-content {
  padding: 25px;
}

.project-content h3 {
  font-size: 20px;
  color: #2c3e50;
  margin-bottom: 10px;
}

.project-content p {
  color: #666;
  font-size: 14px;
  margin-bottom: 15px;
  line-height: 1.6;
}

.project-tags {
  display: flex;
  gap: 10px;
  margin-bottom: 15px;
  flex-wrap: wrap;
}

.tag {
  display: inline-block;
  background-color: #e8f4f8;
  color: #667eea;
  padding: 6px 12px;
  border-radius: 20px;
  font-size: 12px;
  font-weight: bold;
}

.project-link {
  color: #667eea;
  text-decoration: none;
  font-weight: bold;
  transition: color 0.3s;
}

.project-link:hover {
  color: #764ba2;
}

/* ========== CONTACT SECTION (MOBILE) ========== */

.contact {
  padding: 40px 0;
  background-color: white;
}

.contact h2 {
  font-family: 'Playfair Display', serif;
  font-size: 28px;
  color: #2c3e50;
  margin-bottom: 15px;
  text-align: center;
}

.contact-intro {
  text-align: center;
  color: #666;
  margin-bottom: 40px;
  font-size: 16px;
}

.contact-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 40px;
}

.contact-info h3 {
  font-size: 18px;
  color: #2c3e50;
  margin-bottom: 15px;
}

.contact-info ul {
  list-style: none;
  margin-bottom: 30px;
}

.contact-info li {
  margin-bottom: 12px;
  color: #555;
  font-size: 15px;
}

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

.social-link {
  display: inline-block;
  padding: 10px 20px;
  background-color: #667eea;
  color: white;
  text-decoration: none;
  border-radius: 5px;
  transition: background-color 0.3s;
  font-weight: bold;
  font-size: 14px;
}

.social-link:hover {
  background-color: #764ba2;
}

/* Contact Form */
.contact-form {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.form-group {
  display: flex;
  flex-direction: column;
}

.form-group label {
  font-weight: bold;
  margin-bottom: 8px;
  color: #2c3e50;
}

.form-group input,
.form-group textarea {
  padding: 12px 15px;
  border: 1px solid #ddd;
  border-radius: 5px;
  font-family: 'Lato', sans-serif;
  font-size: 14px;
  transition: border-color 0.3s;
}

.form-group input:focus,
.form-group textarea:focus {
  outline: none;
  border-color: #667eea;
  box-shadow: 0 0 8px rgba(102, 126, 234, 0.2);
}

.submit-btn {
  padding: 12px 30px;
  background-color: #667eea;
  color: white;
  border: none;
  border-radius: 5px;
  font-weight: bold;
  cursor: pointer;
  transition: background-color 0.3s;
  font-size: 16px;
}

.submit-btn:hover {
  background-color: #764ba2;
}

/* ========== FOOTER ========== */

.footer {
  background-color: #2c3e50;
  color: white;
  text-align: center;
  padding: 30px 20px;
  font-size: 14px;
}

.footer p {
  margin-bottom: 8px;
}

/* ========== TABLET (481px+) ========== */

@media (min-width: 481px) {
  .header-content {
    padding: 0 30px;
  }

  .nav {
    flex-direction: row;
    gap: 25px;
  }

  .hero h1 {
    font-size: 42px;
  }

  .hero .tagline {
    font-size: 20px;
  }

  .about .container {
    max-width: 95%;
  }

  .skills {
    grid-template-columns: 1fr 1fr;
  }

  .projects-grid {
    grid-template-columns: 1fr 1fr;
  }

  .project-image {
    height: 200px;
  }

  .contact-grid {
    grid-template-columns: 1fr 1fr;
    gap: 50px;
  }

  .contact-form {
    gap: 25px;
  }
}

/* ========== DESKTOP (769px+) ========== */

@media (min-width: 769px) {
  .container {
    max-width: 1200px;
    padding: 0 30px;
  }

  .hero {
    height: 500px;
  }

  .hero h1 {
    font-size: 52px;
  }

  .hero .tagline {
    font-size: 22px;
  }

  .about {
    padding: 60px 0;
  }

  .about .container {
    max-width: 100%;
  }

  .projects {
    padding: 60px 0;
  }

  .projects-grid {
    grid-template-columns: 1fr 1fr 1fr;
    gap: 40px;
  }

  .project-image {
    height: 250px;
  }

  .contact {
    padding: 60px 0;
  }

  .contact-grid {
    gap: 60px;
  }
}

Checklist hoàn thành

✅ Checklist dự án:

**HTML:**
– [ ] Sử dụng semantic tags (header, nav, main, section, article, footer)
– [ ] Viewport meta tag
– [ ] Google Fonts
– [ ] Tất cả nội dung có id/class rõ ràng
– [ ] HTML sạch, không thừa tag

**CSS:**
– [ ] Mobile first approach
– [ ] Responsive design (3+ breakpoints)
– [ ] Color scheme chuyên nghiệp
– [ ] Typography tốt (font, size, line-height)
– [ ] Hover effects & transitions
– [ ] Flexbox/Grid cho layout
– [ ] Box shadow, border-radius cho đẹp

**UX/UI:**
– [ ] Tất cả link hoạt động
– [ ] Button có hover effect
– [ ] Text dễ đọc (contrast tốt)
– [ ] Padding/margin cân đối
– [ ] Touch-friendly (buttons ≥ 44px)

**Performance:**
– [ ] Compress images
– [ ] Minimize CSS
– [ ] Smooth animations (không quá 0.3s)
– [ ] Fast load time

**Testing:**
– [ ] Test trên mobile (375px)
– [ ] Test trên tablet (768px)
– [ ] Test trên desktop (1920px)
– [ ] Test trên thực tế (iOS, Android, Chrome, Firefox, Safari)

Bước tiếp theo & Nâng cấp

Sau khi hoàn thành dự án cơ bản, bạn có thể nâng cấp:

  • JavaScript: Thêm interactivity (form validation, smooth scroll, menu toggle)
  • Animation: Thêm CSS animation (fade-in, slide-in khi scroll)
  • Dark mode: Toggle giữa light/dark theme
  • Blog: Thêm section blog với bài viết
  • Search: Tính năng tìm kiếm dự án
  • Multilingual: Hỗ trợ nhiều ngôn ngữ
  • SEO: Optimize cho tìm kiếm Google
  • Deploy: Đăng trực tuyến (GitHub Pages, Vercel, Netlify)

Tóm tắt

  • HTML semantic: header, nav, main, section, article, footer
  • CSS mobile-first: Desktop enhancement với min-width
  • Responsive design: Mobile, Tablet, Desktop
  • Professional typography: Google Fonts, hierarchy, spacing
  • Colors & effects: Gradients, shadows, transitions, hover effects
  • UX/UI best practices: Accessibility, touch-friendly, clear hierarchy
  • Fully functional: Tất cả links hoạt động, form có layout đúng

🎯 Bài tập hoàn thành

✅ Hoàn thành mini project này bằng cách:

  1. Copy HTML từ bài trên (hoặc viết từ đầu theo ý của bạn)
  2. Copy CSS từ bài trên (hoặc tùy chỉnh colors, fonts)
  3. Thay đổi nội dung: tên, info, dự án theo thông tin của bạn
  4. Test responsive: DevTools (F12) → Device Toolbar (Ctrl+Shift+M)
  5. Test trên thực tế: mở trên điện thoại, tablet, desktop
  6. Tối ưu hóa: compress images, check performance, fix bugs
  7. Deploy: Đẩy lên GitHub, deploy trên Vercel/Netlify (tuỳ chọn)
  8. Chia sẻ: Gửi link cho bạn bè, mentor, nhà tuyển dụng

🎉 Chúc mừng! Bạn đã hoàn thành khóa học HTML & CSS cơ bản và xây dựng được một trang Portfolio thực sự! Đây là bước đầu tiên để trở thành một lập trình viên web. Tiếp theo, bạn nên học JavaScript, React, hoặc Backend để phát triển kỹ năng thêm.

Chúc bạn thành công trên con đường học lập trình! 🚀

Để lại bình luận

Email của bạn sẽ không được hiển thị.