0

[Series 100 Bài Học HTML/CSS Thực Chiến - Bài 02]: "Dọn Cỏ" Trình Duyệt Với CSS Reset, Làm Chủ Box-Sizing & Thiết Lập Bộ Biến Màu Cam Shopee (:root)

Chào mừng anh em quay trở lại với hành trình 100 Bài Học Làm Chủ HTML/CSS Qua Dự Án Clone Shopee!

Ở Bài 01, chúng ta đã dựng xong bộ khung xương HTML5 chuẩn ngữ nghĩa (index.html). Tuy nhiên, khi mở file lên trình duyệt, chắc hẳn bạn sẽ thấy một vài điều rất "chướng mắt":

  1. Toàn bộ trang web bị cách lề một khoảng trắng nhỏ (khoảng 8px) ở cả 4 cạnh dù chúng ta chưa hề viết một dòng CSS nào.

  2. Các danh sách <ul>, <li> tự động có dấu chấm đen tròn và bị thụt lề sâu vào trong.

  3. Các thẻ tiêu đề <h2>, <h3> tự động có khoảng cách trên dưới rất lớn và mỗi trình duyệt (Chrome, Safari, Firefox) lại hiển thị khoảng cách này một kiểu khác nhau!

Nguyên nhân là do mỗi trình duyệt đều tích hợp sẵn một bộ CSS mặc định gọi là User Agent Stylesheet. Trong Bài 02 hôm nay, trước khi bắt tay vào tô màu cho thanh Header Shopee, chúng ta sẽ học cách làm những việc mà mọi kỹ sư Frontend chuyên nghiệp đều làm khi khởi tạo dự án: Reset CSS, chuẩn hóa Box Model (box-sizing), áp dụng thủ thuật 62.5% Font-size và khai báo Design Tokens (Biến CSS :root) chuẩn thương hiệu Shopee.

1. CSS Reset & Box-Sizing: Đưa mọi trình duyệt về cùng một vạch xuất phát

Bài toán kích thước hộp (CSS Box Model)

Trong CSS, mọi thẻ HTML đều là một chiếc hộp chữ nhật được cấu thành từ 4 lớp: Content (Nội dung) →\rightarrow Padding (Đệm trong) →\rightarrow Border (Viền) →\rightarrow Margin (Lề ngoài).

Hãy quan sát sơ đồ cấu tạo CSS Box Model dưới đây để hình dung rõ vị trí của từng lớp:

image.png

Mặc định, trình duyệt sử dụng cơ chế box-sizing: content-box. Điều này gây ra một cơn ác mộng khi chia cột giao diện Shopee:

Ví dụ thực tế: Bạn thiết kế một thẻ sản phẩm (product-card) rộng 200px. Sau đó, bạn thêm padding: 15px để chữ không bị dính sát mép và border: 1px để tạo viền.

Lúc này, chiều rộng thực tế của thẻ sản phẩm bị phình to thành: 200px + 15px (trái) + 15px (phải) + 1px (viền trái) + 1px (viền phải) = 232px! Kết quả là hàng 5 sản phẩm của bạn bị tràn khung và rớt dòng ngay lập tức.

Để giải quyết triệt để, chúng ta chuyển toàn bộ trang sang chế độ box-sizing: border-box. Khi khai báo width: 200px, tổng chiều rộng của cả hộp (bao gồm luôn cả padding và border) sẽ luôn cố định đúng bằng 200px.

Chế độ box-sizing Công thức tính chiều rộng thực tế Tác động đến Layout
content-box
(Mặc định)
width + padding + border Thêm padding hoặc viền làm hộp phình to, gây vỡ lưới giao diện.
border-box
(Khuyên dùng)
Cố định bằng đúng giá trị width đã khai báo Tự động co phần content lại khi thêm padding/border, giữ nguyên kích thước khối.

2. Thủ thuật "Hack" font-size: 62.5% để tính đơn vị rem siêu tốc

Trên các dự án thực tế như Shopee, chúng ta hạn chế dùng đơn vị cứng px cho cỡ chữ và khoảng cách, mà ưu tiên dùng đơn vị tương đối rem (phụ thuộc vào font-size của thẻ gốc <html>) để dễ dàng phóng to/thu nhỏ toàn trang trên điện thoại.

  • Mặc định, font-size của trình duyệt là 16px (tức là 1rem = 16px).

  • Nhưng nếu muốn chữ của giá sản phẩm là 14px hoặc 18px, bạn phải bấm máy tính: 14 / 16 = 0.875rem — rất lẻ và mất thời gian nhẩm tính!

Giải pháp của dân chuyên nghiệp: Đặt font-size: 62.5% tại thẻ html.

  • Vì 62.5%×16px=10px62.5\% \times 16\text{px} = 10\text{px}, nên lúc này 1rem sẽ tròn trĩnh bằng 10px!

  • Muốn cỡ chữ 14px →\rightarrow Gõ 1.4rem.

  • Muốn cỡ chữ 20px →\rightarrow Gõ 2.0rem.

  • Muốn chiều cao thanh tìm kiếm 40px →\rightarrow Gõ 4.0rem.

3. Biến CSS (:root) — Quản lý bảng màu Shopee tập trung

Màu cam đặc trưng của Shopee (#ee4d2d) sẽ xuất hiện ở hàng trăm chỗ: nền Header, nút Tìm kiếm, giá tiền, nhãn Yêu thích, viền sản phẩm khi di chuột vào... Nếu gõ cứng mã màu #ee4d2d ở 200 chỗ trong code, đến ngày chiến dịch "Sale Sinh Nhật" cần đổi sang tông màu Đỏ Đậm, bạn sẽ phải đi sửa tay 200 lần!

Đó là lý do chúng ta sử dụng CSS Variables (Biến trong CSS) đặt trong bộ chọn gốc :root. Chỉ cần sửa giá trị tại :root, toàn bộ 1000 thành phần trên trang web sẽ tự động đổi màu theo trong 1 giây.

4. Thực hành: Viết code cho reset.css và base.css

Bây giờ, hãy mở thư mục dự án shopee-clone-100days mà chúng ta đã tạo ở Bài 01. Chúng ta sẽ cập nhật cấu trúc thư mục CSS thành 3 file tách biệt để dễ quản lý:

Plaintext

shopee-clone-100days/
├── assets/
│   ├── css/
│   │   ├── reset.css    (Xóa khoảng trắng mặc định của trình duyệt)
│   │   ├── base.css     (Chứa biến màu :root, font chữ, khung lưới chung)
│   │   └── main.css     (CSS riêng cho từng thành phần giao diện Shopee)
│   └── images/
└── index.html

Bước 1: Tạo file ./assets/css/reset.css

Hãy mở file reset.css và gõ đoạn code dọn dẹp các thuộc tính mặc định rườm rà của trình duyệt:

CSS

/* ./assets/css/reset.css */

/* 1. Áp dụng border-box cho toàn bộ phần tử và pseudo-elements */
*,
*::before,
*::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

/* 2. Xóa dấu chấm đầu dòng của các danh sách */
ul,
ol {
    list-style: none;
}

/* 3. Xóa gạch chân mặc định của thẻ link và kế thừa màu chữ */
a {
    text-decoration: none;
    color: inherit;
}

/* 4. Giúp hình ảnh không bị tràn khỏi khung chứa */
img,
picture,
svg {
    display: block;
    max-width: 100%;
}

/* 5. Đồng bộ font chữ cho các thẻ form (vì mặc định input/button không nhận font của body) */
input,
button,
textarea,
select {
    font: inherit;
    border: none;
    outline: none;
    background: none;
}

button {
    cursor: pointer;
}

Bước 2: Tạo file ./assets/css/base.css (Thiết lập hệ thống màu Shopee)

Tạo thêm file base.css trong thư mục ./assets/css/ và khai báo toàn bộ thông số chuẩn của Shopee:

CSS

/* ./assets/css/base.css */

:root {
    /* BẢNG MÀU THƯƠNG HIỆU SHOPEE (BRAND COLORS) */
    --shopee-primary: #ee4d2d;          /* Cam Shopee chủ đạo */
    --shopee-primary-gradient: linear-gradient(-180deg, #f53d2d, #f63); /* Dải màu cam nền Header */
    --shopee-primary-light: #ffeee8;    /* Cam nhạt (nền nút Thêm vào giỏ) */
    --shopee-mall-red: #d0011b;         /* Đỏ Shopee Mall */
    --shopee-star-gold: #ffce3d;        /* Vàng ngôi sao đánh giá */

    /* BẢNG MÀU TRUNG TÍNH (NEUTRAL COLORS) */
    --white-color: #ffffff;
    --black-color: #000000;
    --text-primary: rgba(0, 0, 0, 0.87);   /* Màu chữ chính (Đen dịu mắt) */
    --text-secondary: rgba(0, 0, 0, 0.54); /* Màu chữ phụ (Đã bán, địa điểm) */
    --bg-body: #f5f5f5;                    /* Màu nền xám nhạt toàn trang của Shopee */
    --border-color: rgba(0, 0, 0, 0.09);   /* Màu viền mảnh giữa các ô */

    /* KÍCH THƯỚC KHUNG GIAO DIỆN (LAYOUT DIMENSIONS) */
    --container-width: 1200px;          /* Chiều rộng chuẩn của khung nội dung Shopee PC */
    --header-height: 120px;             /* Tổng chiều cao Header */
    --navbar-height: 34px;              /* Chiều cao thanh Topbar */
    --header-with-search-height: calc(var(--header-height) - var(--navbar-height));
}

html {
    /* Thủ thuật 62.5%: Giúp 1rem = 10px */
    font-size: 62.5%;
    line-height: 1.6rem;
    font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
    scroll-behavior: smooth;
}

body {
    font-size: 1.4rem; /* Trả cỡ chữ mặc định của trang về 14px chuẩn Shopee */
    color: var(--text-primary);
    background-color: var(--bg-body);
}

/* Class dùng chung để căn giữa nội dung trong khung 1200px */
.grid-container {
    width: 100%;
    max-width: var(--container-width);
    margin: 0 auto; /* Căn giữa khối ra chính giữa màn hình */
}

Bước 3: Áp dụng thử biến màu vào ./assets/css/main.css

Để thấy ngay thành quả rực rỡ sau khi thiết lập biến, hãy mở file main.css và thêm vài dòng CSS đầu tiên cho phần Header và Thân trang:

CSS

/* ./assets/css/main.css */

.shopee-header {
    height: var(--header-height);
    background-image: var(--shopee-primary-gradient);
    color: var(--white-color);
}

.shopee-container {
    padding-top: 3rem;   /* 30px */
    padding-bottom: 5rem; /* 50px */
}

/* Tạo hiệu ứng khung trắng cho các khối nội dung trên nền xám #f5f5f5 */
.category-section,
.flash-sale-section,
.daily-discover-section {
    background-color: var(--white-color);
    margin-top: 1.5rem;  /* 15px */
    padding: 2rem;       /* 20px */
    border-radius: 2px;
    box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
}

Bước 4: Nhúng các file CSS vào index.html theo đúng thứ tự

Mở lại file index.html ở Bài 01, tìm đến thẻ <head> và cập nhật lại phần <link> như sau (Lưu ý: Thứ tự file CSS cực kỳ quan trọng, file reset.css phải nằm trên cùng, tiếp theo là base.css, và cuối cùng mới là main.css):

HTML

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Shopee Việt Nam | Mua và Bán Trên Ứng Dụng Di Động Hoặc Website</title>
    
    <!-- Nhúng CSS theo đúng thứ tự từ gốc đến ngọn -->
    <link rel="stylesheet" href="./assets/css/reset.css">
    <link rel="stylesheet" href="./assets/css/base.css">
    <link rel="stylesheet" href="./assets/css/main.css">
</head>

Đồng thời, trong file index.html, bạn hãy thêm class grid-container vào thẻ <main class="shopee-container grid-container"> để toàn bộ nội dung chính tự động gom gọn vào khung 1200px nằm chính giữa màn hình nhé!

image.png

5. Giải mã dòng code: Điểm nhấn kỹ thuật đáng chú ý

  • Hàm calc() tự động tính toán chiều cao: Trong base.css, bạn có thấy dòng --header-with-search-height: calc(var(--header-height) - var(--navbar-height)); không? Thay vì tự trừ tay 120px - 34px = 86px, chúng ta dùng hàm calc() kết hợp biến CSS. Sau này nếu bạn tăng chiều cao thanh Navbar lên 40px, vùng chứa thanh tìm kiếm sẽ tự động co lại còn 80px mà không bao giờ bị tràn khung!

  • Sự tương phản giữa --bg-body: #f5f5f5 và --white-color: #ffffff: Rất nhiều bạn mới học làm web thường để nền trang màu trắng tinh (#fff), dẫn đến các khối sản phẩm bị chìm nghỉm. Mẹo thiết kế của Shopee là phủ một lớp nền xám cực nhẹ (#f5f5f5) cho thẻ <body>, sau đó cho các khối Danh mục, Flash Sale màu trắng tinh (#ffffff). Sự chênh lệch sắc độ nhẹ nhàng này giúp các khối nội dung tự động nổi bật lên mà không cần kẻ viền đen thô kệch.

6. Bài tập thực hành cuối bài & Hẹn gặp ở Bài 03!

Khi F5 lại trình duyệt lúc này, bạn sẽ thấy sự lột xác hoàn toàn: khoảng trắng thừa ở 4 góc màn hình đã biến mất, dải màu Cam Đỏ đặc trưng của Shopee đã xuất hiện trên cùng, và các khối nội dung bên dưới đã nằm gọn gàng trong những chiếc hộp trắng rộng 1200px giữa nền xám thanh lịch!

Thử thách cho bạn trước khi qua Bài 03:

  1. Hãy thử vào base.css, đổi giá trị của biến --shopee-primary-gradient sang tông màu Xanh Dương của Tiki (linear-gradient(-180deg, #1a94ff, #0d5cb6)) rồi F5 trình duyệt để cảm nhận sức mạnh của biến CSS :root, sau đó đổi lại màu cam Shopee nhé.

  2. Thêm class grid-container vào bên trong <header> để các chữ trên Header cũng thẳng hàng dọc với phần thân trang bên dưới.

Ở Bài 03, chúng ta sẽ đi sâu vào vũ khí mạnh mẽ nhất để dàn trang ngang trong CSS hiện đại: Flexbox (display: flex) để hoàn thiện thanh Top Navbar của Shopee (căn trái danh mục Kênh Người Bán, căn phải Đăng Ký/Đăng Nhập, tạo các vạch ngăn cách tinh tế giữa các nút)!


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.