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
Mục lục
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ư:
<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:
<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;
<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
<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;
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>
<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:
<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 ^^