Câu trả lời này có hai phần chính:
- Hiểu cách liên kết hoạt động trong CSS Grid.
- Sáu phương pháp để định tâm trong CSS Grid.
Nếu bạn chỉ quan tâm đến các giải pháp, hãy bỏ qua phần đầu tiên.
Cấu trúc và phạm vi bố trí lưới
Để hiểu đầy đủ cách thức định tâm hoạt động trong một thùng chứa lưới, điều quan trọng trước tiên là phải hiểu cấu trúc và phạm vi của bố cục lưới.
Cấu trúc HTML của một thùng chứa lưới có ba cấp độ:
Mỗi cấp độ này độc lập với các cấp độ khác, về mặt áp dụng các thuộc tính lưới.
Các phạm vi của một container lưới được giới hạn trong một mối quan hệ cha-con.
Điều này có nghĩa là một thùng chứa lưới luôn là cha mẹ và một mục lưới luôn là con. Thuộc tính lưới chỉ hoạt động trong mối quan hệ này.
Hậu duệ của một thùng chứa lưới ngoài trẻ em không phải là một phần của bố trí lưới và sẽ không chấp nhận các thuộc tính lưới. (Ít nhất là cho đến khi subgrid
tính năng này được triển khai, điều này sẽ cho phép hậu duệ của các mục lưới tôn trọng các dòng của thùng chứa chính.)
Dưới đây là một ví dụ về các khái niệm cấu trúc và phạm vi được mô tả ở trên.
Hãy tưởng tượng một lưới giống như tic-tac-toe.
article {
display: inline-grid;
grid-template-rows: 100px 100px 100px;
grid-template-columns: 100px 100px 100px;
grid-gap: 3px;
}
Bạn muốn trung tâm của X và O trong mỗi ô.
Vì vậy, bạn áp dụng định tâm ở cấp độ container:
article {
display: inline-grid;
grid-template-rows: 100px 100px 100px;
grid-template-columns: 100px 100px 100px;
grid-gap: 3px;
justify-items: center;
}
Nhưng do cấu trúc và phạm vi bố trí lưới, justify-items
trên container tập trung vào các mục lưới, không phải nội dung (ít nhất là không trực tiếp).
article {
display: inline-grid;
grid-template-rows: 100px 100px 100px;
grid-template-columns: 100px 100px 100px;
grid-gap: 3px;
justify-items: center;
}
section {
border: 2px solid black;
font-size: 3em;
}
<article>
<section>X</section>
<section>O</section>
<section>X</section>
<section>O</section>
<section>X</section>
<section>O</section>
<section>X</section>
<section>O</section>
<section>X</section>
</article>
Vấn đề tương tự với align-items
: Nội dung có thể được đặt ở giữa là sản phẩm phụ, nhưng bạn đã mất thiết kế bố cục.
article {
display: inline-grid;
grid-template-rows: 100px 100px 100px;
grid-template-columns: 100px 100px 100px;
grid-gap: 3px;
justify-items: center;
align-items: center;
}
article {
display: inline-grid;
grid-template-rows: 100px 100px 100px;
grid-template-columns: 100px 100px 100px;
grid-gap: 3px;
justify-items: center;
align-items: center;
}
section {
border: 2px solid black;
font-size: 3em;
}
<article>
<section>X</section>
<section>O</section>
<section>X</section>
<section>O</section>
<section>X</section>
<section>O</section>
<section>X</section>
<section>O</section>
<section>X</section>
</article>
Để tập trung vào nội dung, bạn cần thực hiện một cách tiếp cận khác. Đề cập lại đến cấu trúc và phạm vi bố trí lưới, bạn cần coi mục lưới là cha mẹ và nội dung là con.
article {
display: inline-grid;
grid-template-rows: 100px 100px 100px;
grid-template-columns: 100px 100px 100px;
grid-gap: 3px;
}
section {
display: flex;
justify-content: center;
align-items: center;
border: 2px solid black;
font-size: 3em;
}
article {
display: inline-grid;
grid-template-rows: 100px 100px 100px;
grid-template-columns: 100px 100px 100px;
grid-gap: 3px;
}
section {
display: flex;
justify-content: center;
align-items: center;
border: 2px solid black;
font-size: 3em;
}
<article>
<section>X</section>
<section>O</section>
<section>X</section>
<section>O</section>
<section>X</section>
<section>O</section>
<section>X</section>
<section>O</section>
<section>X</section>
</article>
bản demo jsFiddle
Sáu phương pháp định tâm trong lưới CSS
Có nhiều phương pháp để định tâm các mục lưới và nội dung của chúng.
Đây là lưới 2x2 cơ bản:
grid-container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-auto-rows: 75px;
grid-gap: 10px;
}
/* can ignore styles below; decorative only */
grid-container {
background-color: lightyellow;
border: 1px solid #bbb;
padding: 10px;
}
grid-item {
background-color: lightgreen;
border: 1px solid #ccc;
}
<grid-container>
<grid-item>this text should be centered</grid-item>
<grid-item>this text should be centered</grid-item>
<grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
<grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
</grid-container>
Hộp linh hoạt
Đối với một cách đơn giản và dễ dàng để tập trung vào nội dung của các mục lưới, hãy sử dụng flexbox.
Cụ thể hơn, làm cho các mục lưới vào một thùng chứa flex.
Không có xung đột, vi phạm spec hoặc vấn đề khác với phương pháp này. Nó sạch sẽ và hợp lệ.
grid-item {
display: flex;
align-items: center;
justify-content: center;
}
grid-container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-auto-rows: 75px;
grid-gap: 10px;
}
grid-item {
display: flex; /* new */
align-items: center; /* new */
justify-content: center; /* new */
}
/* can ignore styles below; decorative only */
grid-container {
background-color: lightyellow;
border: 1px solid #bbb;
padding: 10px;
}
grid-item {
background-color: lightgreen;
border: 1px solid #ccc;
}
<grid-container>
<grid-item>this text should be centered</grid-item>
<grid-item>this text should be centered</grid-item>
<grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
<grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
</grid-container>
Xem bài đăng này để được giải thích đầy đủ:
Bố cục lưới
Theo cùng một cách mà một vật phẩm flex cũng có thể là một thùng chứa flex, một vật phẩm lưới cũng có thể là một vật chứa lưới. Giải pháp này tương tự như giải pháp flexbox ở trên, ngoại trừ việc định tâm được thực hiện bằng lưới, không phải thuộc tính flex.
grid-container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-auto-rows: 75px;
grid-gap: 10px;
}
grid-item {
display: grid; /* new */
align-items: center; /* new */
justify-items: center; /* new */
}
/* can ignore styles below; decorative only */
grid-container {
background-color: lightyellow;
border: 1px solid #bbb;
padding: 10px;
}
grid-item {
background-color: lightgreen;
border: 1px solid #ccc;
}
<grid-container>
<grid-item>this text should be centered</grid-item>
<grid-item>this text should be centered</grid-item>
<grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
<grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
</grid-container>
auto
lề
Sử dụng margin: auto
để các mục lưới trung tâm theo chiều dọc và chiều ngang.
grid-item {
margin: auto;
}
grid-container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-auto-rows: 75px;
grid-gap: 10px;
}
grid-item {
margin: auto;
}
/* can ignore styles below; decorative only */
grid-container {
background-color: lightyellow;
border: 1px solid #bbb;
padding: 10px;
}
grid-item {
background-color: lightgreen;
border: 1px solid #ccc;
}
<grid-container>
<grid-item>this text should be centered</grid-item>
<grid-item>this text should be centered</grid-item>
<grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
<grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
</grid-container>
Để căn giữa nội dung của các mục lưới, bạn cần đặt mục vào trong hộp chứa lưới (hoặc flex), bọc các mục ẩn danh trong các phần tử của riêng chúng ( vì chúng không thể được nhắm mục tiêu trực tiếp bởi CSS ) và áp dụng lề cho các phần tử mới.
grid-item {
display: flex;
}
span, img {
margin: auto;
}
grid-container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-auto-rows: 75px;
grid-gap: 10px;
}
grid-item {
display: flex;
}
span, img {
margin: auto;
}
/* can ignore styles below; decorative only */
grid-container {
background-color: lightyellow;
border: 1px solid #bbb;
padding: 10px;
}
grid-item {
background-color: lightgreen;
border: 1px solid #ccc;
}
<grid-container>
<grid-item><span>this text should be centered</span></grid-item>
<grid-item><span>this text should be centered</span></grid-item>
<grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
<grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
</grid-container>
Thuộc tính căn chỉnh hộp
Khi xem xét sử dụng các thuộc tính sau để căn chỉnh các mục lưới, hãy đọc phần trên auto
lề trên.
align-items
justify-items
align-self
justify-self
https://www.w3.org/TR/css-align-3/#property-index
text-align: center
Để căn giữa nội dung theo chiều ngang trong một mục lưới, bạn có thể sử dụng thuộc text-align
tính.
grid-container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-auto-rows: 75px;
grid-gap: 10px;
text-align: center; /* new */
}
/* can ignore styles below; decorative only */
grid-container {
background-color: lightyellow;
border: 1px solid #bbb;
padding: 10px;
}
grid-item {
background-color: lightgreen;
border: 1px solid #ccc;
}
<grid-container>
<grid-item>this text should be centered</grid-item>
<grid-item>this text should be centered</grid-item>
<grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
<grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
</grid-container>
Lưu ý rằng đối với định tâm dọc, vertical-align: middle
sẽ không hoạt động.
Điều này là do thuộc vertical-align
tính chỉ áp dụng cho các thùng chứa nội tuyến và ô bảng.
grid-container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-auto-rows: 75px;
grid-gap: 10px;
text-align: center; /* <--- works */
vertical-align: middle; /* <--- fails */
}
/* can ignore styles below; decorative only */
grid-container {
background-color: lightyellow;
border: 1px solid #bbb;
padding: 10px;
}
grid-item {
background-color: lightgreen;
border: 1px solid #ccc;
}
<grid-container>
<grid-item>this text should be centered</grid-item>
<grid-item>this text should be centered</grid-item>
<grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
<grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
</grid-container>
Người ta có thể nói rằng display: inline-grid
thiết lập một thùng chứa cấp độ nội tuyến, và điều đó là đúng. Vậy tại sao không vertical-align
hoạt động trong các mục lưới?
Lý do là trong bối cảnh định dạng lưới , các mục được coi là các phần tử mức khối.
6.1. Hiển thị mục lưới
Các display
giá trị của một mục lưới được blockified : nếu quy định display
của một đứa trẻ trong dòng chảy của một phần tử tạo ra một container lưới là một giá trị inline-level, nó tính đến khối cấp của nó tương đương.
Trong ngữ cảnh định dạng khối , một cái gì đó thuộc vertical-align
tính ban đầu được thiết kế cho, trình duyệt không mong đợi tìm thấy một phần tử cấp khối trong một thùng chứa cấp độ nội tuyến. Đó là HTML không hợp lệ.
Định vị CSS
Cuối cùng, có một giải pháp định tâm CSS chung cũng hoạt động trong Grid: định vị tuyệt đối
Đây là một phương pháp tốt để định tâm các đối tượng cần được loại bỏ khỏi luồng tài liệu. Ví dụ: nếu bạn muốn:
Đơn giản chỉ cần đặt thành position: absolute
phần được đặt ở giữa và position: relative
trên tổ tiên sẽ đóng vai trò là khối chứa (thường là cha mẹ). Một cái gì đó như thế này:
grid-item {
position: relative;
text-align: center;
}
span {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
grid-container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-auto-rows: 75px;
grid-gap: 10px;
}
grid-item {
position: relative;
text-align: center;
}
span, img {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
/* can ignore styles below; decorative only */
grid-container {
background-color: lightyellow;
border: 1px solid #bbb;
padding: 10px;
}
grid-item {
background-color: lightgreen;
border: 1px solid #ccc;
}
<grid-container>
<grid-item><span>this text should be centered</span></grid-item>
<grid-item><span>this text should be centered</span></grid-item>
<grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
<grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
</grid-container>
Đây là một lời giải thích đầy đủ cho cách thức hoạt động của phương pháp này:
Đây là phần về định vị tuyệt đối trong thông số lưới: