All posts
How to center a DIV? ✋😭🤚
fehtmlcss

How to center a DIV? ✋😭🤚

Hoang Nguyen V.'s avatarHoang Nguyen V.
Table of Contents17 sections

Cách căn giữa một div — từ xịn đến "thôi kệ nó"

Câu hỏi kinh điển của mọi thời đại frontend. Có nhiều cách lắm, nhưng không phải cách nào cũng nên dùng.


Tier 1 — Best Practice (dùng đi không ai judge)

1. Flexbox — GOAT của mọi layout

.parent {
  display: flex;
  justify-content: center; /* căn ngang */
  align-items: center;     /* căn dọc */
}

Khi nào dùng: Hầu hết mọi trường hợp. Layout 1 chiều, responsive tốt, browser support gần như 100%. Đây là cách mặc định nên nghĩ đến đầu tiên.


2. CSS Grid — khi bạn muốn flex nhưng "fancy" hơn

.parent {
  display: grid;
  place-items: center; /* shorthand của align-items + justify-items */
}

Hoặc đầy đủ hơn:

.parent {
  display: grid;
  justify-content: center;
  align-content: center;
}

Khi nào dùng: Layout 2 chiều, hoặc khi place-items: center đọc xong ngầu hơn. Cũng rất modern, browser support ổn.


3. margin: auto — classic, không bao giờ lỗi thời

.child {
  width: 300px; /* PHẢI có width */
  margin: 0 auto;
}

Khi nào dùng: Căn ngang element có width cố định, kiểu wrapper/container của cả trang. Không căn dọc được nhé.


Tier 2 — Dùng được, nhưng có caveats

4. text-align: center (cho inline elements)

.parent {
  text-align: center;
}

.child {
  display: inline-block;
}

Khi nào dùng: Child là text, button, icon — tức là inline hoặc inline-block. Dùng cho block element thì không ăn thua đâu nha.


5. Flexbox trên chính element đó (self-centering)

.child {
  display: flex;
  justify-content: center;
  align-items: center;
}

Cách này căn nội dung bên trong child, không phải căn child trong parent. Dễ nhầm lắm.


6. width: fit-content + margin: auto

.child {
  width: fit-content;
  margin: 0 auto;
}

Không cần biết width trước, browser tự tính. Khá tiện nhưng browser support cần check thêm với IE (nếu dự án bạn vẫn còn support IE thì... xin chia buồn 🕯️).


Tier 3 — Dùng được trong hoàn cảnh rất cụ thể

7. position: absolute + transform

.parent {
  position: relative;
}

.child {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

Vấn đề: Child bị lấy ra khỏi document flow — các element khác không "biết" nó tồn tại. Dễ gây layout bug, khó responsive, khó maintain.

Dùng khi nào còn hợp lý: Modal, tooltip, overlay, loading spinner — những thứ cố tình nằm trên mọi thứ và không cần interact với flow.


8. position: absolute + margin: auto (ít biết hơn)

.parent {
  position: relative;
}

.child {
  position: absolute;
  top: 0; right: 0; bottom: 0; left: 0;
  margin: auto;
  width: 200px;  /* cần có width và height */
  height: 100px;
}

Ít phổ biến hơn cách trên, nhưng không bị lệch khi scroll như transform. Vẫn có vấn đề out-of-flow như trên.


Tier 4 — Tệ, đừng làm nếu có lựa chọn khác

9. padding cứng tay

.parent {
  padding: 50px 100px;
}

Magic number. Resize màn hình là vỡ ngay. Không responsive. Đây là "center" bằng niềm tin, không phải bằng code.


10. line-height trick (cho text)

.child {
  height: 50px;
  line-height: 50px; /* bằng với height */
}

Chỉ hoạt động với single-line text. Nếu text xuống dòng là vỡ luôn. Legacy code đầy cái này, đừng viết mới nữa.


11. vertical-align: middle + display: table-cell

.parent {
  display: table-cell;
  vertical-align: middle;
  text-align: center;
}

Vẫn hoạt động, nhưng đây là giải pháp từ thời chưa có flexbox. Nếu thấy cái này trong codebase thì biết code đó "có tuổi" rồi 🫡


12. Dùng JavaScript để set position

const el = document.querySelector('.child');
const parent = el.parentElement;
el.style.marginLeft = (parent.offsetWidth - el.offsetWidth) / 2 + 'px';

Không cần giải thích tại sao tệ. Đừng. 🚫


Tóm tắt nhanh

Cách

Căn ngang

Căn dọc

Responsive

Nên dùng?

Flexbox

⭐⭐⭐

Grid place-items

⭐⭐⭐

margin: auto

⭐⭐⭐

text-align + inline-block

⭐⭐

absolute + transform

⚠️

⭐ (modal only)

padding cứng

⚠️

⚠️

line-height

JavaScript

🚫


TL;DR: Dùng Flexbox. Nếu không thì Grid. Nếu không thì margin: auto. Còn lại chỉ dùng khi thực sự cần và biết mình đang làm gì.