Định tâm trong CSS Grid


179

Tôi đang cố gắng tạo một trang đơn giản với CSS Grid.

Điều tôi không làm được là tập trung văn bản từ HTML vào các ô lưới tương ứng.

Tôi đã thử đặt nội dung trong các phần riêng biệt divcả bên trong và bên ngoài left_bgright_bgbộ chọn và chơi với một số thuộc tính CSS không có kết quả.

Làm thế nào để tôi làm điều này?

html,
body {
  margin: 0;
  padding: 0;
}

.container {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 100vh;
  grid-gap: 0px 0px;
}

.left_bg {
  display: subgrid;
  background-color: #3498db;
  grid-column: 1 / 1;
  grid-row: 1 / 1;
  z-index: 0;
}

.right_bg {
  display: subgrid;
  background-color: #ecf0f1;
  grid-column: 2 / 2;
  grid_row: 1 / 1;
  z-index: 0;
}

.left_text {
  grid-column: 1 / 1;
  grid-row: 1 / 1;
  position: relative;
  z-index: 1;
  justify-self: center;
  font-family: Raleway;
  font-size: large;
}

.right_text {
  grid-column: 2 / 2;
  grid_row: 1 / 1;
  position: relative;
  z-index: 1;
  justify-self: center;
  font-family: Raleway;
  font-size: large;
}
<div class="container">
  <!--everything on the page-->

  <div class="left_bg">
    <!--left background color of the page-->
  </div>
</div>

<div class="right_bg">
  <!--right background color of the page-->
</div>

<div class="left_text">
  <!--left side text content-->
  <p>Review my stuff</p>

  <div class="right_text">
    <!--right side text content-->
    <p>Hire me!</p>
  </div>
</div>


1
Vui lòng kiểm tra liên kết w3.org/Style/Examples/007/center.en.html , tôi hy vọng nó sẽ hữu ích.
Ali

Câu trả lời:


433

Câu trả lời này có hai phần chính:

  1. Hiểu cách liên kết hoạt động trong CSS Grid.
  2. 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 độ:

  • thùng chứa
  • mục
  • Nội dung

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 subgridtí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;
}

nhập mô tả hình ảnh ở đây

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-itemstrê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).

nhập mô tả hình ảnh ở đây

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;
}

nhập mô tả hình ảnh ở đây

Để 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;
}

nhập mô tả hình ảnh ở đây

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;
}

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.


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;
}

Để 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;
}


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 autolề 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-aligntính.

Lưu ý rằng đối với định tâm dọc, vertical-align: middlesẽ không hoạt động.

Điều này là do thuộc vertical-aligntính chỉ áp dụng cho các thùng chứa nội tuyến và ô bảng.

Người ta có thể nói rằng display: inline-gridthiế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-alignhoạ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 displaygiá trị của một mục lưới được blockified : nếu quy định displaycủ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-aligntí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: absolutephần được đặt ở giữa và position: relativetrê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%);
}

Đâ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:


Xin chào Michael, tôi đã tự hỏi liệu có thể chỉ bằng cách sử dụng lưới để thay đổi kích thước mỗi cột thành kích thước của cột nhỏ nhất trong hàng không?
The Codee 18/03/18

@TheCodesee, điều đó có thể có thể, tùy thuộc vào tất cả các yêu cầu của bạn .. Bạn có mẫu mã không? Hoặc xem xét đăng một câu hỏi mới với tất cả các chi tiết.
Michael Benjamin

grid-container& grid-itemcác thẻ HTML?
diEcho

1
Chúng là các thẻ HTML tùy chỉnh . Bạn có thể tạo các thẻ của riêng bạn, như tôi đã làm cho bản demo này. stackoverflow.com/q/36380449/3597276 @ pro.mean
Michael Benjamin

5
Đây là một câu trả lời tuyệt vời, cảm ơn bạn. Nó khiến tôi nhận ra, trong hai ví dụ đầu tiên của bạn, rằng giữa flexgrid, align-itemsvẫn giữ nguyên nhưng vì một lý do nào đó justify-contenttrở thànhjustify-items
WoJ

11

Bạn có thể sử dụng flexbox để căn giữa văn bản của bạn. Nhân tiện, không cần thêm container vì văn bản được coi là mục flex ẩn danh.

Từ thông số kỹ thuật flexbox :

Mỗi dòng con của một thùng chứa flex trở thành một vật phẩm flex và mỗi dòng văn bản liền kề được chứa trực tiếp bên trong một thùng chứa flex được bọc trong một vật phẩm flex ẩn danh . Tuy nhiên, một mục flex ẩn danh chỉ chứa khoảng trắng (nghĩa là các ký tự có thể bị ảnh hưởng bởi thuộc white-spacetính) sẽ không được hiển thị (giống như khi có display:none).

Vì vậy, chỉ cần tạo các mục lưới dưới dạng flex container ( display: flex), và thêm align-items: centerjustify-content: centervào giữa theo chiều dọc và chiều ngang.

Cũng thực hiện tối ưu hóa HTML và CSS:

html,
body {
  margin: 0;
  padding: 0;
}

.container {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 100vh;
  
  font-family: Raleway;
  font-size: large;
}

.left_bg,
.right_bg {
  display: flex;
  align-items: center;
  justify-content: center;
}

.left_bg {
  background-color: #3498db;
}

.right_bg {
  background-color: #ecf0f1;
}
<div class="container">
  <div class="left_bg">Review my stuff</div>
  <div class="right_bg">Hire me!</div>
</div>


9

Thậm chí đừng cố gắng sử dụng flex; ở lại với lưới css !! :)

https://jsfiddle.net/ctt3bqr0/

justify-self: center;
align-self: center;

đang làm công việc trung tâm ở đây.

Nếu bạn muốn tập trung vào một cái gì đó bên divtrong ô bên trong ô lưới, bạn cần xác định lưới lồng nhau để làm cho nó hoạt động. (Xin vui lòng nhìn vào fiddle cả hai ví dụ hiển thị ở đó.)

https://css-tricks.com/snippets/css/complete-guide-grid/

Chúc mừng!


Tôi đã tự hỏi về các lưới lồng nhau. Cảm ơn đã chỉ cho tôi làm thế nào nó làm tôi đoán. Vì vậy, bạn nghĩ flex nên tránh với lưới hoặc nó là tốt để kết hợp?
củ cải đường

Nó tốt để kết hợp nhưng bạn cần chắc chắn rằng bạn đang sử dụng đúng công cụ cho công việc. Tìm một chút thời gian và xem bài thuyết trình của Rachels, điều đó sẽ làm rõ rất nhiều cho bạn trong chủ đề về lưới css. youtu.be/3vJE3bVoF-Q
Konrad Albrecht

Vấn đề với cách tiếp cận này xảy ra khi bạn sử dụng đường viền trên các mục lưới ...
Andrew

2
Điều này có thể được rút ngắn bằng place-self: center;.
DevonDahon

6

Thuộc tính tốc ký địa điểm CSS đặt các thuộc tính align-items và justify-items tương ứng. Nếu giá trị thứ hai không được đặt, giá trị đầu tiên cũng được sử dụng cho nó.

.parent {
  display: grid;
  place-items: center;
}

place-itemshiện không được hỗ trợ ở rìa
Konrad Albrecht

1

Hãy thử sử dụng flex:

Bản demo của Plunker: https://plnkr.co/edit/nk02ojKuXD2tAqZiWvf9

/* Styles go here */

html,
body {
  margin: 0;
  padding: 0;
}

.container {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 100vh;
  grid-gap: 0px 0px;
}

.left_bg {
  background-color: #3498db;
  grid-column: 1 / 1;
  grid-row: 1 / 1;
  z-index: 0;
  display: flex;
  justify-content: center;
  align-items: center;

}

.right_bg {
  background-color: #ecf0f1;
  grid-column: 2 / 2;
  grid_row: 1 / 1;
  z-index: 0;
  display: flex;
  justify-content: center;
  align-items: center;
}

.text {
  font-family: Raleway;
  font-size: large;
  text-align: center;
}

HTML

    <div class="container">
  <!--everything on the page-->

  <div class="left_bg">
    <!--left background color of the page-->
    <div class="text">
      <!--left side text content-->
      <p>Review my stuff</p>
    </div>
  </div>

  <div class="right_bg">
    <!--right background color of the page-->
    <div class="text">
      <!--right side text content-->
      <p>Hire me!</p>
    </div>
  </div>
</div>

-2

Bạn muốn điều này?

html,
body {
  margin: 0;
  padding: 0;
}

.container {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 100vh;
  grid-gap: 0px 0px;
}

.left_bg {
  display: subgrid;
  background-color: #3498db;
  grid-column: 1 / 1;
  grid-row: 1 / 1;
  z-index: 0;
}

.right_bg {
  display: subgrid;
  background-color: #ecf0f1;
  grid-column: 2 / 2;
  grid_row: 1 / 1;
  z-index: 0;
}

.text {
  font-family: Raleway;
  font-size: large;
  text-align: center;
}
<div class="container">
  <!--everything on the page-->

  <div class="left_bg">
    <!--left background color of the page-->
    <div class="text">
      <!--left side text content-->
      <p>Review my stuff</p>
    </div>
  </div>

  <div class="right_bg">
    <!--right background color of the page-->
    <div class="text">
      <!--right side text content-->
      <p>Hire me!</p>
    </div>
  </div>
</div>


1
Không hẳn. Các văn bản nên được liên kết theo chiều dọc quá.
củ cải đường

Sử dụng.text{ font-family: Raleway; font-size: large; text-align: center; -webkit-transform: rotate(-90deg); -moz-transform: rotate(-90deg); }
Renato siqueira

-2

Tôi biết câu hỏi này là một vài tuổi, nhưng tôi ngạc nhiên khi thấy rằng không ai đề nghị:

   text-align: center;

đây là một thuộc tính phổ quát hơn nội dung biện minh và chắc chắn không phải là duy nhất đối với lưới, nhưng tôi thấy rằng khi xử lý văn bản, đó là điều mà câu hỏi này đặc biệt hỏi về việc nó căn chỉnh văn bản vào trung tâm mà không ảnh hưởng đến không gian giữa các mục lưới, hoặc định tâm dọc. Nó tập trung văn bản theo chiều ngang, nơi nó đứng trên trục thẳng đứng. Tôi cũng tìm thấy nó để loại bỏ một lớp phức tạp mà nội dung biện minh và sắp xếp các mục thêm vào. justify-content và align-item ảnh hưởng đến toàn bộ mục lưới hoặc các mục, căn chỉnh văn bản tập trung vào văn bản mà không ảnh hưởng đến vùng chứa nó. Hy vọng điều này sẽ giúp ích.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.