Chuyển tới nội dung chính

[Medium] 🏷️ Đơn vị CSS

1. Giải thích sự khác biệt giữa px, em, rem, vw, vh​

Bảng so sánh nhanh​

Đơn vịLoạiTương đối vớiBị ảnh hưởng bởi chaCông dụng phổ biến
pxTuyệt đốiPixel màn hìnhKhôngĐường viền, bóng đổ, chi tiết nhỏ
emTương đốifont-size của phần tử chaCóPadding, margin (theo kích thước chữ)
remTương đốifont-size của phần tử gốcKhôngFont, khoảng cách, kích thước chung
vwTương đối1% chiều rộng viewportKhôngChiều rộng responsive, phần tử full-width
vhTương đối1% chiều cao viewportKhôngChiều cao responsive, section toàn màn hình

Giải thích chi tiết​

px (Pixels)​

Định nghĩa : Đơn vị tuyệt đối, 1px = một điểm pixel trên màn hình

Đặc điểm :

  • Kích thước cố định, không thay đổi theo bất kỳ thiết lập nào
  • Kiểm soát chính xác nhưng thiếu linh hoạt
  • Không thuận lợi cho thiết kế responsive và accessibility

Khi nào dùng :

/* Phù hợp cho */
border: 1px solid #000; /* Đường viền */
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); /* Bóng đổ */
border-radius: 4px; /* Bo góc nhỏ */

/* Không nên dùng cho */
font-size: 16px; /* Nên dùng rem cho font */
width: 1200px; /* Nên dùng % hoặc vw cho chiều rộng */

em​

Định nghĩa : Bội số của font-size phần tử cha

Đặc điểm :

  • Cộng dồn khi kế thừa (cấu trúc lồng nhau sẽ cộng thêm)
  • Linh hoạt cao nhưng dễ mất kiểm soát
  • Phù hợp cho các tình huống cần co giãn theo phần tử cha

Ví dụ tính toán :

.parent {
font-size: 16px;
}

.child {
font-size: 1.5em; /* 16px × 1.5 = 24px */
padding: 1em; /* 24px × 1 = 24px (tương đối với font-size của chính nó) */
}

.grandchild {
font-size: 1.5em; /* 24px × 1.5 = 36px (hiệu ứng cộng dồn!) */
}

Khi nào dùng :

/* Phù hợp cho */
.button {
font-size: 1rem;
padding: 0.5em 1em; /* Padding theo kích thước font của nút */
}

.card-title {
font-size: 1.2em; /* Tương đối với font cơ bản của card */
margin-bottom: 0.5em; /* Khoảng cách theo kích thước tiêu đề */
}

/* Cẩn thận cộng dồn khi lồng nhau */

rem (Root em)​

Định nghĩa : Bội số của font-size phần tử gốc (<html>)

Đặc điểm :

  • Không cộng dồn khi kế thừa (luôn tương đối với phần tử gốc)
  • Dễ quản lý và bảo trì
  • Thuận tiện cho việc co giãn toàn cục
  • Một trong những đơn vị được khuyến nghị nhất

Ví dụ tính toán :

html {
font-size: 16px; /* Mặc định trình duyệt */
}

.element {
font-size: 1.5rem; /* 16px × 1.5 = 24px */
padding: 2rem; /* 16px × 2 = 32px */
margin: 1rem 0; /* 16px × 1 = 16px */
}

.nested .element {
font-size: 1.5rem; /* Vẫn là 24px, không cộng dồn! */
}

Khi nào dùng :

/* Được khuyến nghị nhất cho */
html {
font-size: 16px; /* Thiết lập cơ sở */
}

body {
font-size: 1rem; /* Nội dung chính 16px */
}

h1 {
font-size: 2.5rem; /* 40px */
}

p {
font-size: 1rem; /* 16px */
margin-bottom: 1rem; /* 16px */
}

.container {
padding: 2rem; /* 32px */
max-width: 75rem; /* 1200px */
}

/* Thuận tiện cho dark mode hoặc điều chỉnh accessibility */
@media (prefers-reduced-motion: reduce) {
html {
font-size: 18px; /* Tất cả đơn vị rem tự động phóng to */
}
}

vw (Viewport Width)​

Định nghĩa : 1% chiều rộng viewport (100vw = chiều rộng viewport)

Đặc điểm :

  • Đơn vị responsive thực sự
  • Thay đổi theo thời gian thực khi kích thước cửa sổ trình duyệt thay đổi
  • Lưu ý: 100vw bao gồm chiều rộng thanh cuộn

Ví dụ tính toán :

/* Giả sử chiều rộng viewport 1920px */
.element {
width: 50vw; /* 1920px × 50% = 960px */
font-size: 5vw; /* 1920px × 5% = 96px */
}

/* Giả sử chiều rộng viewport 375px (điện thoại) */
.element {
width: 50vw; /* 375px × 50% = 187.5px */
font-size: 5vw; /* 375px × 5% = 18.75px */
}

Khi nào dùng :

/* Phù hợp cho */
.hero {
width: 100vw; /* Banner toàn chiều rộng */
margin-left: calc(-50vw + 50%); /* Vượt ra ngoài container */
}

.hero-title {
font-size: clamp(2rem, 5vw, 5rem); /* Font responsive */
}

.responsive-box {
width: 80vw;
max-width: 1200px; /* Thêm giới hạn tối đa */
}

/* Tránh */
body {
width: 100vw; /* Sẽ gây thanh cuộn ngang (vì bao gồm chiều rộng thanh cuộn) */
}

vh (Viewport Height)​

Định nghĩa : 1% chiều cao viewport (100vh = chiều cao viewport)

Đặc điểm :

  • Phù hợp cho hiệu ứng toàn màn hình
  • Trên thiết bị di động cần lưu ý vấn đề thanh địa chỉ
  • Có thể bị ảnh hưởng khi bàn phím bật lên

Khi nào dùng :

/* Phù hợp cho */
.hero-section {
height: 100vh; /* Trang chủ toàn màn hình */
}

.fullscreen-modal {
height: 100vh;
width: 100vw;
}

.sidebar {
height: 100vh;
position: sticky;
top: 0;
}

/* Giải pháp thay thế cho thiết bị di động */
.hero-section {
height: 100vh;
height: 100dvh; /* Chiều cao viewport động (đơn vị mới hơn) */
}

/* Căn giữa theo chiều dọc */
.center-content {
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}

Khuyến nghị thực tế và best practice​

1. Xây dựng hệ thống font responsive​

/* Thiết lập cơ sở */
html {
font-size: 16px; /* Mặc định desktop */
}

@media (max-width: 768px) {
html {
font-size: 14px; /* Tablet */
}
}

@media (max-width: 480px) {
html {
font-size: 12px; /* Điện thoại */
}
}

/* Tất cả phần tử dùng rem sẽ tự động co giãn */
h1 {
font-size: 2.5rem;
} /* Desktop 40px, Điện thoại 30px */
p {
font-size: 1rem;
} /* Desktop 16px, Điện thoại 12px */

2. Kết hợp các đơn vị khác nhau​

.card {
/* Chiều rộng responsive + giới hạn phạm vi */
width: 90vw;
max-width: 75rem;

/* rem cho khoảng cách */
padding: 2rem;
margin: 1rem auto;

/* px cho chi tiết */
border: 1px solid #ddd;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.card-title {
/* clamp kết hợp nhiều đơn vị, co giãn mượt mà */
font-size: clamp(1.25rem, 3vw, 2rem);
}

Mẫu trả lời phỏng vấn​

Cấu trúc trả lời :

1. **px** : Chi tiết nhỏ pixel -> đường viền, bóng đổ, bo góc nhỏ
2. **rem** : Nền tảng ổn định -> font, khoảng cách, kích thước chính
3. **em** : Theo phần tử cha
4. **vw** : Theo chiều rộng viewport -> chiều rộng responsive
5. **vh** : Theo chiều cao viewport -> section toàn màn hình
  1. Định nghĩa nhanh

    • px là đơn vị tuyệt đối, còn lại là tương đối
    • em tương đối với cha, rem tương đối với gốc
    • vw/vh tương đối với kích thước viewport
  2. Khác biệt chính

    • rem không cộng dồn, em cộng dồn (khác biệt chính)
    • vw/vh responsive thực sự, nhưng cần lưu ý vấn đề thanh cuộn
  3. Ứng dụng thực tế

    • px : Đường viền 1px, bóng đổ và chi tiết khác
    • rem : Font, khoảng cách, container (phổ biến nhất, dễ bảo trì)
    • em : Padding nút (khi cần theo co giãn font)
    • vw/vh : Banner full-width, section toàn màn hình, font responsive kết hợp clamp
  4. Best practice

    • Thiết lập html font-size làm cơ sở
    • Dùng clamp() kết hợp các đơn vị khác nhau
    • Lưu ý vấn đề vh trên di động (có thể dùng dvh)

Reference​