Cách bạn căn giữa bằng CSS

Cách bạn căn giữa bằng CSS

Có rất nhiều cách để bạn canh giữa một thành phần trong một trang web. Sau đây mình xin chia sẻ một vài phương pháp bạn có thể sử dụng thường xuyên trong công việc. Bạn có thể áp dụng linh hoạt các phương pháp sau đây tùy thuộc tình huống và mục đích sử dụng

Canh giữa theo chiều ngang

Canh giữa bằng CSS text-align: center

Chữ và hình ảnh trong HTML có CSS mặc định là

display: inline; // image là inline-block

Vì vậy, đơn giản nhất bạn chỉ cần thêm CSS text-align: center vào parent của chữ hoặc hình đó. CSS này cũng có thể áp dụng cho các inline HTML khác như thẻ <a>, <span>, <sub>…. Các bạn có thể tìm hiểu thêm trong bài Tìm hiểu về HTML blocks và inline

text-align: center;

Ví dụ như:

Đây là text ở giữa và hình ở giữa
<div class="parentDiv">
  Đây là text ở giữa và hình ở giữa <br> //Hình và chữ sẽ cùng một hàng nếu không có <br>
  <img src="https://picsum.photos/200">
</div>


<style>
  .parentDiv {
    text-align: center;
  }
</style>

Canh giữa một block bằng margin

Giả sử bạn muốn canh giữa một block HTML element như <div>, <table> hoặc <img>, bạn có thể dùng margin để làm việc đó như ví dụ sau:

Đây là .centerDiv nằm giữa
<div id="div1" class="wrapper">
  <div class="centerDiv">
    Đây là .centerDiv nằm giữa
  </div>
</div>


<style>
  #div1.wrapper{
    padding: 10px 30px;
    text-align: center;
    background-color: #a1f5e5;
  }

  #div1 .centerDiv{
    max-width: 300px; // hoặc
    //width: 300px;
    margin-right: auto;
    margin-left: auto;
    background-color: #000;
    color: #fff;
    font-weight: bold;
  }
</style>

Bởi vì “.centerDiv” là một <div> có default CSS là display: block nên mặc định chiều rộng của “.centerDiv” sẽ là 100%, nó sẽ trải dài hết chiều rộng của <body> hoặc parent element. Khi đó, margin-right và margin-left sẽ luôn luôn bằng 0. Vì vậy, “.centerDiv” cần được set width hoặc max-width để nhỏ hơn parent element của nó, khi margin-left: auto và margin-right: 0 thì “.centerDiv” sẽ được canh phải vì để thỏa điều kiện margin-right: 0;

Đây là .centerDiv nằm phải
<div id="div2" class="wrapper">
  <div class="centerDiv">
    Đây là .centerDiv nằm phải
  </div>
</div>


<style>
  #div2.wrapper{
    padding: 10px 30px;
    text-align: center;
    background-color: #a1f5e5;
  }

  #div2 .centerDiv{
    max-width: 300px; // hoặc
    //width: 300px;
    margin-right: 0;
    margin-left: auto;
    background-color: #000;
    color: #fff;
    font-weight: bold;
  }
</style>

Và cũng tương tự khi margin-left: 0 và margin-right: auto, “centerDiv” sẽ canh trái

Đây là .centerDiv nằm trái
<div id="div3" class="wrapper">
  <div class="centerDiv">
    Đây là .centerDiv nằm trái
  </div>
</div>


<style>
  #div3.wrapper{
    padding: 10px 30px;
    text-align: center;
    background-color: #a1f5e5;
  }

  #div3 .centerDiv{
    max-width: 300px; // hoặc
    //width: 300px;
    margin-right: auto;
    margin-left: 0;
    background-color: #000;
    color: #fff;
    font-weight: bold;
  }
</style>

Do đó, khi “centerDiv” có cả hai margin-right và margin-left đều auto, giá trị của hai margin sẽ bằng nhau, vì vậy “centerDiv” sẽ được canh giữa

margin-right: auto;
margin-left: auto;
Hai giá trị margin-right và margin-left bằng nhau

Canh giữa một block bằng CSS Flexbox

Thông thường, CSS Flexbox được dùng để format HTML, chẳng hạn như chia cột. Ngoài ra, chúng ta còn có thể sử dụng CSS Flexbox để canh chỉnh các element một cách nhanh chóng và hiệu quả. Cơ bản khi sử dụng CSS Flexbox, chúng ta cần một thẻ parent và các thẻ con bên trong. Ví dụ, chúng ta sẽ canh giữa hình ảnh sau:

Đây là #div4 display: flex;
Sử dụng align-items: center; trên #div4 để canh giữa hình ảnh

<div id="div4">
  <p>
    Đây là #div4 display: flex; <br/>
    Sử dụng align-items: center; trên #div4 để canh giữa hình ảnh
  </p>
  <img src="https://picsum.photos/200/200">
</div>

<style>
  #div4 {
    display: flex;
    padding: 30px;
    align-items: center; //Để canh giữa hình ảnh và chữ
    flex-direction: column; //Để hình và chữ không cùng một hàng
    border: 2px solid #000;
  }
</style>

Canh giữa theo chiều dọc

Đơn giản nhất: hãy sử dụng CSS flexbox

Chính xác là vậy, bạn có thể canh giữa mọi thứ với flexbox theo chiều ngang và cả chiều dọc. Các bạn có thể tham khảo một vài ví dụ sau đây

<div class="flex-to-center">
 <img src="https://picsum.photos/200/300">
</div>

<style>
  .flex-to-center {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 600px;
    border: 2px solid #000;
  }
</style>

Đây là text được canh giữa

<div class="flex-to-center">
 <p>Đây là text được canh giữa</p>
</div>

<style>
  .flex-to-center {
    display: flex;
    align-items: center;
    text-align: center;
    height: 400px;
    border: 2px solid #000;
  }
</style>
Đây là box màu xanh, chữ trắng được canh giữa
<div class="flex-to-center">
 <div class="box-green">Đây là box màu xanh, chữ trắng được canh giữa</div>
</div>

<style>
  .box-green {
    color: #fff;
    display: flex;
    align-items: center;
    text-align: center;
    width: 200px;
    height: 200px;
    background-color: green;
  }

  .flex-to-center {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 400px;
    border: 2px solid #000;
  }
</style>

Canh giữa theo chiều dọc (và cả chiều ngang) bằng position: absolute

Nếu bạn có một element có width và height xác định (set WIDTH và HEIGHT CSS hoặc hình ảnh), bạn có thể sử dụng position absolute để canh giữa theo chiều dọc một cách cực kì dễ dàng

<div class="boxRelative">
 <div class="boxAbsolute"></div>
</div>

<style>
  .boxRelative {
    position: relative;
    height: 400px;
    border: 2px solid #000;
  }

  .boxAbsolute {
    position: absolute;
    top: 0;
    bottom: 0;
    margin-top: auto;
    margin-bottom: auto;
    width: 200px;
    height: 200px;
    background-color: red;
  }
</style>

Mấu chốt để absolute element hoạt động được là parent element phải có position là relative hoặc absolute (khác static). Và để element đó nằm giữa theo chiều dọc, thì 4 dòng sau đây sẽ quyết định điều đó

    top: 0;
    bottom: 0;
    margin-top: auto;
    margin-bottom: auto;

Mình xin giải thích dòng CSS sau một cách ngắn gọn. Khi chúng ta chỉ có,

    top: 0;
    bottom: 0;

thì box màu đỏ của chúng ta sẽ như thế này

<div class="boxRelative">
 <div class="boxAbsolute1"></div>
</div>

<style>
  .boxRelative {
    position: relative;
    height: 400px;
    border: 2px solid #000;
  }

  .boxAbsolute1 {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 200px;
    height: 200px;
    background-color: red;
  }
</style>

Vì top: 0 nên box màu đỏ sẽ nằm sát trên cùng, nhưng box đỏ có height là 200px nên nó không thể nào sát đáy được. CSS margin-top và margin-bottom auto sẽ giúp box màu đỏ tự canh giữa như trên

Giả sử, box màu đỏ không có set CSS height thì sao nhỉ, nó sẽ như thế này

<div class="boxRelative">
 <div class="boxAbsolute2"></div>
</div>

<style>
  .boxRelative {
    position: relative;
    height: 400px;
    border: 2px solid #000;
  }

  .boxAbsolute2 {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 200px;
    background-color: red;
  }
</style>

Top: 0 và Bottom: 0 sẽ kéo height full hết parent element cho thỏa điều kiện đầu và đuôi đều chạm đỉnh và đáy (Bạn có thể dễ dàng suy ra điều tương tự đôi với right và left). Và suy ra, khi bạn quyết định sử dụng position absolute để canh giữa theo chiều dọc cho một element nào đó, bạn sẽ cần:

top: 0;
bottom: 0;
width: 200px //không có width, width mặc định  = 0
height: 200px //sẽ không cần set height nếu element đó là hình <img>
margin-top: auto;
margin-bottom: auto;

Tương tự cho việc căn giữa chiều ngang đối với trường hợp sử dụng CSS position absolute

<div class="boxRelative">
 <div class="boxAbsolute"></div>
</div>

<style>
  .boxRelative {
    position: relative;
    height: 400px;
    border: 2px solid #000;
  }

  .boxAbsolute {
    position: absolute;
    top: 0;
    right: 0
    bottom: 0;
    left: 0;
    margin-top: auto;
    margin-right: auto;
    margin-bottom: auto;
    margin-left: auto;
    width: 200px;
    height: 200px;
    background-color: red;
  }
</style>

Và kết quả:

Canh giữa bằng table

Trong table, bạn có thể canh giữa theo chiều dọc bằng CSS vertical-align: center

Text center vertical Text Text
<table class="table-border">
  <tbody>
    <tr>
      <td class="vertical-middle">
        Text center vertical
      </td>
      <td>
        Text
      </td>
      <td>
        Text
      </td>
   </tr>
  </tbody>
</table>

<style>
   .table-border > tbody > tr > .vertical-middle {
     vertical-align: middle;
     background-color: red;
     color: #fff;
  }

   .table-border > tbody > tr > td {
     height: 80px;
     padding: 5px 20px;
     text-align: center;
     vertical-align: top;
     color: black;
     border: 2px solid #000;
  }
</style>

Tuy nhiên, không phải lúc nào bạn cũng có thể sử dụng <table> và việc sử dụng <table> cũng làm cho code của bạn dài dòng và phức tạp không cần thiết. Bạn có thể “giả lập” table như sau:

This is vertical center text
<div class="d-table">
  <div class="table-cell"> This is vertical center text </div>
</div>

<style>
  .d-table {
    display: table;
    color: #fff;
  }


  .d-table .table-cell {
    display: table-cell;
    height: 80px;
    padding: 5px 10px;
    vertical-align: middle;
    background-color: red;
  }
</style>

CSS này sẽ biến div block của bạn thành table

display: table;

Và CSS này sẽ biến các child div thành các cell trong table

display: table-cell;

Vì các div bây giờ hoạt động như một ô trong table, do đó, chúng có thể dùng vertical-align: middle để canh giữa nội dung trong các ô “giả lập” đó

Kết luận

Nhìn chung, nhờ có CSS, bạn có rất rất nhiều cách để canh giữa một thành phần về cả chiều ngang và dọc. Có nhiều phương pháp khác trên mạng sẽ hướng dẫn bạn sử dụng line-height, transfrom… nhưng đôi với mình, những cách đó không hiệu quả trong việc bảo trì code và gây trở ngại trong việc làm responsive layout. Bạn có thể sử dụng chúng trong vài tình huống nhất định. Đối với mình, không có cách tốt hay dở, chỉ có phương pháp phù hợp nhất trong tùy hoàn cảnh mà thôi.

Chúc các bạn code vui ^^

Hãy comment ý kiến của bạn