+47

Căn giữa phần tử trong CSS

1. Theo chiều ngang

Đó có phải là phần tử inline hay inline-* (như text hay links)?

Bạn có thể căn giữa phần tử inline theo chiều ngang bên trong phần tử cha block-level với text-align

.center-parent {
  text-align: center;
}

Đó có phải là một phần tử block-level?

Bạn có thể căn giữa một phần tử block-level bằng việc gán cho margin-left và margin-right giá trị auto (và phần tử này cũng cần được set width, nếu ko thì nó chiếm toàn bộ chiều rộng và không cần căn giữa). Ta có thể thực hiện việc này bằng shorthand sau:

.center-me {
  margin: 0 auto;
}

Có phải có hơn một phần tử block-level?

Nếu bạn có hai hoặc nhiều hơn các phần tử block-level cần được căn giữa trong một hàng. Tốt hơn hết bạn nên thay đổi cách chúng display sang inline-block.

.center-parent {
  text-align: center;
}

.center-me {
  display: inline-block;
}

hoặc bạn cũng có thể sử dụng flexbox:

.center-parent {
  display: flex;
  justify-content: center;
}

2. Theo chiều dọc

Đó có phải là phần tử inline hay inline-* (như text hay links)?

Phần tử đó chỉ chiếm một dòng?

Thường những phần tử inline/text có thể căn giữa chỉ vì chúng có padding trên và dưới bằng nhau:

.center-me {
   padding-top: 30px;
   padding-bottom: 30px;
}

Nếu không thể sử dụng padding vì lý do nào đó và bạn đang tìm cách căn giữa text mà bạn nghĩ sẽ không wrap, bạn có thể set line-height bằng với height:

.center-me {
  height: 100px;
  line-height: 100px;
  white-space: nowrap;
}

Phần tử đó chiếm nhiều dòng?

Việc set padding bằng nhau với top và bottom cũng có thể giups căn giữa những phần tử nhiều dòng. Tuy nhiên trong trường hợp phần tử được tạo ra tương tự với một table cell thì ta có thể gán thuộc tính vetical-align với giá trị middle

.center-me {
  verticle-align: middle;
}

Bạn cũng có thể dùng flexbox với giá trị của flex-direction là column và fix height:

.flex-center-vertically {
  display: flex;
  justify-content: center;
  flex-direction: column;
  height: 400px;
}

Nếu cả 2 cách trên đều không hoạt động ta có thể sử dụng kỹ thuật "ghost element" trong đó phần tử pseudo với full-height đặt trong phần tử chứa và text sẽ được gán vertical-align với giá trị middle

.ghost-center {
  position: relative;
}

.ghost-center:before {
  content: "";
  display: inline-block;
  height: 100%;
  width: 1%;
  vertical-align: middle;
}

.ghost-center p {
  display: inline-block;
  verticle-align: middle;
}

Đó có phải là một phần tử block-level?

Bạn biết height của phần tử đó?

Thông thường một phần tử sẽ không có height cố định nhưng nếu trường hợp đó xảy ra bạn có thể căn giữa phần tử đó theo chiều dọc như sau:

.center-parent {
  position: relative;
}

.center-me {
  position: absolute;
  top: 50%;
  height: 100px;
  margin-top: -50px;
}

Bạn không biết height của phần tử đó?

Tương tự kỹ thuật với trường hợp biết height tuy nhiên thay vì sử dụng margin-top âm ta sẽ dịch chuyển phần tử đó một khoảng bằng một nửa height của nó lên trên theo chiều dọc

.center-parent {
  position: relative;
}

.center-me {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
}

Liệu bạn có thể sử dụng flexbox?

Không có gì ngạc nhiên khi việc này được thực hiện một cách dễ dàng với flexbox

.center-parent {
  display: flex;
  flex-direction: column;
  align-items: center;
}

3. Cả chiều ngang lẫn chiều dọc

Bạn có thể sử dụng kết hợp những kỹ thuật căn giữa với chiều ngang và chiều dọc ở trên để đạt được điều này tuy nhiên bạn có thể sử dụng những kỹ thuật dưới đây.

Phần tử đó có width và height cố định?

Sử dụng margin âm có giá trị tuyệt đối bằng một nửa width và height của phần tử đó sau khi bạn đã position nó kiểu absolute với top và left 50% sẽ căn giữa nó một cách hoàn hảo trên nhiều trình duyệt.

.center-parent {
  position: relative;
}

.center-me {
  width: 200px;
  height: 100px;
  
  position: absolute;
  top: 50%;
  left: 50%;
  margin: -50px 0 0 -100px;
}

Bạn không biết width và height của phần tử đó?

Bạn có thể dùng thuộc tính transform để dịch chuyển phần tử đó một khoảng bằng một nửa height của nó lên trên và một nửa width của nó sang trái để đạt được kết quả tương tự như trên.

.center-parent {
  position: relative;
}

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

Liệu bạn có thể sử dụng flexbox?

Để căn giữa cả 2 chiều với flexbox bạn cần dùng 2 thuộc tính justify-content và align-items.

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

4. Kết luận

Bạn có thể căn giữa mọi thứ với CSS.

Tham khảo

https://css-tricks.com/centering-css-complete-guide/


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí