อยู่ตรงกลางใน CSS Grid


179

ฉันกำลังพยายามสร้างหน้าง่าย ๆ ด้วย CSS Grid

สิ่งที่ฉันไม่สามารถทำได้คือวางข้อความไว้ที่กึ่งกลางจาก HTML ไปยังเซลล์กริดที่เกี่ยวข้อง

ฉันได้ลองวางเนื้อหาในแยกdivของทั้งด้านในและด้านนอกของleft_bgและright_bgตัวเลือกและเล่นกับคุณสมบัติ CSS บางอย่างเพื่อประโยชน์

ฉันจะทำสิ่งนี้ได้อย่างไร

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
โปรดตรวจสอบลิงก์w3.org/Style/Examples/007/center.en.htmlฉันหวังว่าจะเป็นประโยชน์
อาลี

คำตอบ:


433

คำตอบนี้มีสองส่วนหลัก:

  1. ทำความเข้าใจเกี่ยวกับการจัดตำแหน่งใน CSS Grid
  2. หกวิธีสำหรับการอยู่ตรงกลางใน CSS Grid

หากคุณสนใจเฉพาะโซลูชันให้ข้ามส่วนแรก


โครงสร้างและขอบเขตของเค้าโครงตาราง

เพื่อให้เข้าใจอย่างถ่องแท้ถึงวิธีการทำงานของศูนย์กลางในคอนเทนเนอร์กริดสิ่งสำคัญคือต้องเข้าใจโครงสร้างและขอบเขตของเค้าโครงกริดก่อน

โครงสร้าง HTML ของคอนเทนเนอร์กริดมีสามระดับ:

  • ภาชนะ
  • รายการ
  • หัวข้อ

แต่ละระดับเหล่านี้เป็นอิสระจากระดับอื่นในแง่ของการใช้คุณสมบัติกริด

ขอบเขตของภาชนะตารางจะถูก จำกัด ให้ความสัมพันธ์แม่ลูก

ซึ่งหมายความว่าคอนเทนเนอร์กริดเป็นพาเรนต์เสมอและรายการกริดจะเป็นรายการย่อยเสมอ คุณสมบัติกริดทำงานภายในความสัมพันธ์นี้เท่านั้น

ลูกหลานของคอนเทนเนอร์กริดที่อยู่ถัดจากเด็ก ๆ นั้นไม่ได้เป็นส่วนหนึ่งของเค้าโครงกริดและจะไม่ยอมรับคุณสมบัติกริด (อย่างน้อยก็จนกว่าจะsubgridมีการใช้งานคุณลักษณะนี้ซึ่งจะทำให้ลูกหลานของรายการในตารางเคารพบรรทัดของคอนเทนเนอร์หลัก)

นี่คือตัวอย่างของแนวคิดโครงสร้างและขอบเขตที่อธิบายข้างต้น

ลองนึกภาพตารางที่คล้ายกับโอเอกซ์

article {
  display: inline-grid;
  grid-template-rows: 100px 100px 100px;
  grid-template-columns: 100px 100px 100px;
  grid-gap: 3px;
}

ป้อนคำอธิบายรูปภาพที่นี่

คุณต้องการให้ X และ O เป็นศูนย์กลางในแต่ละเซลล์

ดังนั้นคุณจึงใช้การจัดกึ่งกลางที่ระดับคอนเทนเนอร์:

article {
  display: inline-grid;
  grid-template-rows: 100px 100px 100px;
  grid-template-columns: 100px 100px 100px;
  grid-gap: 3px;
  justify-items: center;
}

แต่เนื่องจากโครงสร้างและขอบเขตของเค้าโครงตารางjustify-itemsบนคอนเทนเนอร์จะจัดกึ่งกลางรายการกริดไม่ใช่เนื้อหา (อย่างน้อยก็ไม่ตรง)

ป้อนคำอธิบายรูปภาพที่นี่

ปัญหาเดียวกันกับalign-items: เนื้อหาอาจอยู่กึ่งกลางเป็นผลพลอยได้ แต่คุณสูญเสียการออกแบบเลย์เอาต์

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

section {
  display: flex;
  justify-content: center;
  align-items: center;
  border: 2px solid black;
  font-size: 3em;
}

ป้อนคำอธิบายรูปภาพที่นี่

การสาธิต jsFiddle


หกวิธีสำหรับการอยู่ตรงกลางใน CSS Grid

มีหลายวิธีสำหรับการจัดกึ่งกลางรายการกริดและเนื้อหา

นี่คือตาราง 2x2 พื้นฐาน:

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>

flexbox

สำหรับวิธีที่ง่ายและสะดวกในการจัดกึ่งกลางเนื้อหาของรายการกริดใช้ flexbox

โดยเฉพาะอย่างยิ่งทำให้รายการตารางเป็นคอนเทนเนอร์แบบยืดหยุ่น

ไม่มีความขัดแย้งการละเมิดข้อมูลจำเพาะหรือปัญหาอื่น ๆ ด้วยวิธีนี้ มันสะอาดและถูกต้อง

grid-item {
  display: flex;
  align-items: center;
  justify-content: center;
}

ดูโพสต์นี้สำหรับคำอธิบายที่สมบูรณ์:


เค้าโครงตาราง

ในลักษณะเดียวกับที่รายการ flex สามารถเป็น flex container รายการ grid สามารถเป็น container grid โซลูชันนี้คล้ายกับโซลูชัน flexbox ด้านบนยกเว้นว่าการจัดกึ่งกลางนั้นทำด้วยกริดไม่ใช่คุณสมบัติแบบเฟล็กซ์


auto อัตรากำไรขั้นต้น

ใช้margin: autoเพื่อจัดรายการกริดในแนวตั้งและแนวนอน

grid-item {
  margin: auto;
}

ในการจัดกึ่งกลางเนื้อหาของรายการกริดคุณต้องทำให้รายการเป็นคอนเทนเนอร์กริด (หรือเฟล็กซ์) ห่อรายการที่ไม่ระบุชื่อในองค์ประกอบของตนเอง ( เนื่องจากไม่สามารถกำหนดเป้าหมายโดยตรงด้วย CSS ) และใช้ระยะขอบกับองค์ประกอบใหม่

grid-item {
  display: flex;
}

span, img {
  margin: auto;
}


คุณสมบัติการจัดตำแหน่งกล่อง

เมื่อพิจารณาการใช้คุณสมบัติต่อไปนี้เพื่อจัดแนวรายการตารางให้อ่านส่วนที่autoระยะขอบด้านบน

  • align-items
  • justify-items
  • align-self
  • justify-self

https://www.w3.org/TR/css-align-3/#property-index


text-align: center

เมื่อต้องการจัดกึ่งกลางเนื้อหาตามแนวนอนในรายการกริดคุณสามารถใช้text-alignคุณสมบัติได้

โปรดทราบว่าสำหรับการจัดกึ่งกลางแนวตั้งvertical-align: middleจะไม่ทำงาน

นี่เป็นเพราะvertical-alignคุณสมบัติใช้กับคอนเทนเนอร์แบบอินไลน์และเซลล์ตารางเท่านั้น

บางคนอาจบอกว่าdisplay: inline-gridสร้างตู้คอนเทนเนอร์ในระดับและนั่นจะเป็นจริง เหตุใดจึงไม่vertical-alignทำงานในรายการกริด

เหตุผลก็คือในบริบทการจัดรูปแบบกริดรายการจะถือว่าเป็นองค์ประกอบระดับบล็อก

6.1 แสดงรายการกริด

displayค่าของรายการตารางจะblockified : ถ้าระบุdisplayของเด็กในการไหลขององค์ประกอบการสร้างภาชนะตารางเป็นค่าอินไลน์ระดับมันคำนวณเทียบเท่าระดับบล็อกของตน

ในบริบทการจัดรูปแบบบล็อกสิ่งที่vertical-alignคุณสมบัติได้รับการออกแบบมาสำหรับเบราว์เซอร์ไม่ได้คาดหวังว่าจะพบองค์ประกอบระดับบล็อกในคอนเทนเนอร์ระดับ inline นั่นคือ HTML ที่ไม่ถูกต้อง


การวางตำแหน่ง CSS

สุดท้ายมีโซลูชันการจัดกึ่งกลาง CSS ทั่วไปที่ใช้งานได้ใน Grid: การจัดตำแหน่งที่แน่นอน

นี่เป็นวิธีที่ดีสำหรับการจัดกึ่งกลางวัตถุที่ต้องถูกลบออกจากผังเอกสาร ตัวอย่างเช่นหากคุณต้องการ:

เพียงตั้งค่าposition: absoluteองค์ประกอบที่จะให้อยู่กึ่งกลางและposition: relativeบนบรรพบุรุษที่จะทำหน้าที่เป็นบล็อกที่มี (มักจะเป็นผู้ปกครอง) บางสิ่งเช่นนี้

grid-item {
  position: relative;
  text-align: center;
}

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

นี่คือคำอธิบายที่สมบูรณ์เกี่ยวกับวิธีการทำงานของวิธีนี้:

นี่คือส่วนของการวางตำแหน่งที่แน่นอนในข้อมูลจำเพาะของกริด:


สวัสดีไมเคิลฉันสงสัยว่าเป็นไปได้หรือไม่ที่จะใช้กริดเพื่อปรับขนาดแต่ละคอลัมน์ให้มีขนาดเล็กที่สุดในแถว?
ผู้รหัส

@TheCodesee ที่อาจเป็นไปได้ขึ้นอยู่กับความต้องการทั้งหมดของคุณ .. คุณมีตัวอย่างโค้ดหรือไม่? หรือลองโพสต์คำถามใหม่พร้อมรายละเอียดทั้งหมด
Michael Benjamin

เป็นgrid-containerงานgrid-itemที่มีแท็ก HTML?
diEcho

1
พวกเขาเป็นแท็ก HTML ที่กำหนดเอง คุณสามารถสร้างแท็กของคุณเองอย่างที่ฉันทำในการสาธิตนี้ stackoverflow.com/q/36380449/3597276 @ pro.mean
Michael Benjamin

5
นี่คือคำตอบที่ยอดเยี่ยมขอบคุณ มันทำให้ฉันตระหนักในสองตัวอย่างแรกของคุณว่าระหว่างflexและgrid, align-itemsการเข้าพักเดียวกัน แต่ด้วยเหตุผลบางอย่างjustify-contentกลายเป็นjustify-items
WoJ

11

คุณสามารถใช้ flexbox เพื่อจัดกึ่งกลางข้อความของคุณ โดยไม่จำเป็นต้องมีคอนเทนเนอร์เพิ่มเติมเนื่องจากข้อความถูกพิจารณาว่าเป็นรายการ flex แบบไม่ระบุชื่อ

จากข้อกำหนดของ flexbox :

เด็กแต่ละคนในการไหลของภาชนะดิ้นกลายเป็นรายการดิ้นและการทำงานในแต่ละที่ต่อเนื่องกันของข้อความที่มีอยู่โดยตรงภายในภาชนะดิ้นเป็นห่อในที่ไม่ระบุชื่อรายการดิ้น อย่างไรก็ตามไอเท็มเฟล็กต์แบบไม่ระบุชื่อที่มีพื้นที่สีขาวเท่านั้น(เช่นอักขระที่สามารถได้รับผลกระทบจากwhite-spaceคุณสมบัติ) จะไม่ถูกแสดงผล (เช่นเดียวกับที่เป็นdisplay:none)

ดังนั้นเพียงทำเป็นรายการกริดเป็น flex container ( display: flex) แล้วเพิ่มalign-items: centerและจัดjustify-content: centerกึ่งกลางทั้งแนวตั้งและแนวนอน

ดำเนินการเพิ่มประสิทธิภาพของ HTML และ 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

อย่าพยายามใช้ flex อยู่กับ css grid !! :)

https://jsfiddle.net/ctt3bqr0/

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

กำลังทำงานที่ศูนย์กลางอยู่ที่นี่

ถ้าคุณต้องการจัดกึ่งกลางสิ่งที่อยู่ภายในdivที่อยู่ภายในเซลล์กริดคุณจำเป็นต้องกำหนดกริดซ้อนเพื่อให้มันทำงาน (โปรดดูซอทั้งสองตัวอย่างที่แสดงมี)

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

ไชโย!


ฉันสงสัยเกี่ยวกับกริดซ้อนกัน ขอขอบคุณที่แสดงให้ฉันเห็นว่าฉันเดาได้อย่างไร ดังนั้นคุณคิดว่า flex ควรหลีกเลี่ยงกับ grid หรือมันเป็นการรวมที่ดี?
บีทรูท

มันเป็นการรวมที่ดี แต่คุณต้องแน่ใจว่าคุณใช้เครื่องมือที่เหมาะสมสำหรับงาน ค้นหาเวลาและดูการนำเสนอ Rachels ที่จะทำให้ชัดเจนมากสำหรับคุณในหัวข้อของ css grid youtu.be/3vJE3bVoF-Q
Konrad Albrecht

ปัญหาเกี่ยวกับวิธีการนี้เกิดขึ้นเมื่อคุณใช้เส้นขอบบนรายการกริด ...
แอนดรู

2
สิ่งนี้สามารถย่อให้สั้นลงplace-self: center;ได้
DevonDahon

6

CSS ที่สถานรายการทรัพย์สินจดชวเลขชุดรายการที่จัดและปรับ-รายการคุณสมบัติตามลำดับ หากไม่ได้ตั้งค่าที่สองไว้ระบบจะใช้ค่าแรกแทนด้วย

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

place-itemsไม่รองรับขอบในขณะนี้
Konrad Albrecht

1

ลองใช้ flex:

ผู้สาธิตพลั่วเกอร์: 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

คุณต้องการสิ่งนี้?

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
ไม่มาก ข้อความควรจัดตำแหน่งในแนวตั้งด้วย
บีทรูท

ใช้.text{ font-family: Raleway; font-size: large; text-align: center; -webkit-transform: rotate(-90deg); -moz-transform: rotate(-90deg); }
Renato siqueira

-2

ฉันรู้ว่าคำถามนี้มีอายุสองปี แต่ฉันประหลาดใจที่พบว่าไม่มีใครแนะนำ:

   text-align: center;

นี่เป็นคุณสมบัติที่เป็นสากลมากกว่าปรับให้เหมาะสมกับเนื้อหาและไม่เฉพาะเจาะจงกับกริด แต่ฉันพบว่าเมื่อต้องรับมือกับข้อความ ระหว่างรายการกริดหรือการจัดกึ่งกลางแนวตั้ง มันกึ่งกลางข้อความในแนวนอนที่ยืนอยู่บนแกนตั้งของมัน ฉันยังพบว่ามันจะลบเลเยอร์ของความซับซ้อนที่เพิ่มความเหมาะสมของเนื้อหาและการจัดแนวรายการ justify-content และ align-items มีผลกับรายการกริดทั้งหมดหรือ item, text-align จัดกึ่งกลางข้อความโดยไม่ส่งผลกระทบต่อคอนเทนเนอร์ที่อยู่ในหวังว่าสิ่งนี้จะช่วยได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.