px vs rem trong CSS | Root 16px, trick 62.5% và khi nào dùng px cho border

(Cập nhật: 19 tháng 7, 2026 ) CSS px rem root font-size accessibility design token
Kết luận

Font + spacing → rem. Border / hairline / “đúng 1 pixel thiết bị” → px. Root mặc định 16px (1rem = 16px). Trick 62.5% chỉ khi team chấp nhận 1rem ≈ 10px và không trộn với Tailwind mặc định. Trước khi migrate token: lập bảng px→rem bằng PX ↔ REM, rồi test zoom chữ trình duyệt — đó là lý do chọn rem.

Figma ghi 24. Junior viết font-size: 24px. Reviewer bảo “dùng rem”. Intern chia 16 → 1.5rem — đúng. Sprint sau ai đó set html { font-size: 62.5% } copy từ blog 2018 → toàn bộ spacing nhảy, QA báo “letter-spacing như bug”.

Dev VN trong team outsourcing thường inherit repo khách (Mix 62.5% + Tailwind text-base = 1rem). Bài này chốt quy ước, a11y zoom, và bảng convert trước migrate.

Bài viết này giúp bạn

  • Hiểu root 16 vs 62.5%
  • Biết khi nào px vẫn đúng
  • Phân biệt rem / em / px
  • Convert bảng token trước khi đụng codebase
  • Checklist accessibility zoom

px và rem khác nhau ở điểm nào?

pxrem
Bản chấtĐơn vị CSS “tuyệt đối” theo reference pixelTương đối theo font-size của html
User tăng cỡ chữ mặc địnhNhiều chỗ không theo (nếu mọi thứ px)Font/spacing rem scale theo
Đọc designTrùng số FigmaCần chia cho root
Border 1pxỔn địnhCó thể dày/mỏng lạ khi root đổi
/* Khuyến nghị hiện đại */
html {
  font-size: 100%; /* tôn trọng default user — thường 16px */
}

.title {
  font-size: 1.5rem; /* 24px khi root 16 */
  margin-bottom: 1rem;
  border-bottom: 1px solid #e5e7eb; /* border: px */
}
Nên gắn đơn vị nào?
Thuộc tính Ưu tiên Lý do
font-size, line-height (nhiều case) rem Theo root + user preference
padding, margin, gap rem UI scale đồng bộ với chữ
border-width, outline px Hairline ổn định
box-shadow offset nhỏ px (thường) Tránh bóng ‘phình’ khi zoom text
media query breakpoint px hoặc em (tùy team) Nhiều design system vẫn chốt px viewport

Root 16px vs trick 62.5%

Root 16 (mặc định trình duyệt)

24px → 24 / 16 = 1.5rem
32px → 2rem
8px  → 0.5rem

Tailwind, nhiều UI kit, và MDN examples giả định thế giới này. Ưu tiên cho project mới.

Trick 62.5%

html {
  font-size: 62.5%; /* 16 × 0.625 = 10px nếu default user = 16 */
}
body {
  font-size: 1.6rem; /* lại về ~16px cho body */
}
.heading {
  font-size: 2.4rem; /* “như” 24px — chia 10 dễ */
}

Ưu: tính nhẩm nhanh kiểu cũ.
Nhược: thư viện giả định 1rem=16 sẽ sai tỷ lệ; user đổi default font → 62.5% của default mới, không còn đúng “10px thần thánh”; onboarding member mới dễ nhầm.

Quy tắc: một repo một convention. Có 62.5% thì ghi README + comment trên html. Không thì đừng thêm.


Accessibility: zoom chữ ≠ zoom trang

Người dùng (và nhiều chuẩn a11y) tăng cỡ chữ mặc định trình duyệt. Nếu toàn bộ UI là px, layout có thể:

  • Chữ lớn nhưng nút/padding vẫn nhỏ → chạm khó
  • Hoặc chữ bị cắt trong hộp cố định px

Với rem, tăng root kéo theo spacing — form login / nav thường chịu đựng tốt hơn. Test bắt buộc: Firefox/Chrome → cỡ chữ 150–200%, mở trang có input tiếng Việt (dấu thanh), xem có đứt layout không.

Ctrl + zoom cả trang khác với đổi default font — cả hai nên thử; rem giúp nhiều hơn với default font.


Bảng convert trước khi migrate design token

Đừng đổi từng class trong PR 400 file. Làm bảng:

Figma (px)rem @16rem @10 (62.5%)
40.250.4
80.50.8
120.751.2
1611.6
241.52.4
3223.2
4834.8

Dán từng cột vào Chuyển PX ↔ REM: chỉnh base size 16 hoặc 10, nhập px, lấy rem. Export token JSON/--space-* một lần.

🔄 Chuyển đổi px và rem ngay tại đây

px

rem

Khi khách đổi “design system từ 8pt sang 4pt grid”, chỉ cần cập nhật bảng + regenerate — không cãi nhau trên PR từng margin: 13px.


Case study

Repo khách: Tailwind + html { font-size: 62.5% }

text-base (1rem) thành ~10px → chữ toàn site như caption. Fix: xóa 62.5% hoặc custom Tailwind fontSize theo root thật. Không được giữ cả hai im lặng.

Migrate token agency

80 giá trị spacing px trong SCSS. Team chốt root 16, chạy bảng qua tool, thay $space-24: 24px$space-24: 1.5rem, giữ $border-hairline: 1px. Test zoom 200% trên checkout — nút không còn dính nhau.


Checklist

  • Convention root đã ghi (16 vs 62.5%)
  • Font/spacing → rem
  • Border hairline → px
  • Không trộn em lồng nhau không kiểm soát
  • Bảng convert đã review với design
  • Zoom chữ 150%+ trên form chính
  • Lib UI (Tailwind/MUI) khớp giả định rem

Liên quan

  • Chuyển PX ↔ REM — đổi base, convert nhanh
  • Fluid type (clamp) — bước sau khi đã ổn rem
  • Contrast chữ — a11y không chỉ là đơn vị

Bookmark lý do: một chỗ chốt 16 vs 62.5%, px cho border, và quy trình bảng convert token trước khi đụng PR lớn.