วิธีการตั้งศูนย์ div ในแนวตั้งภายใน div div หลัก


146

ฉันกำลังพยายามหาที่เก็บสีน้ำเงินตรงกลางของสีชมพู แต่ดูเหมือนว่าvertical-align: middle;จะไม่ทำงานในกรณีนั้น

<div style="display: block; position: absolute; left: 50px; top: 50px;">
    <div style="text-align: left; position: absolute;height: 56px;vertical-align: middle;background-color: pink;">
        <div style="background-color: lightblue;">test</div>
    </div>
</div>

ผลลัพธ์:

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

ความคาดหวัง:

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

กรุณาแนะนำว่าฉันจะบรรลุสิ่งนั้นได้อย่างไร

Jsfiddle


1
มีเหตุผลทำไมคุณใช้position: absoluteทุกที่?
Vucko

การvertical-align: middle;ทำงานกับdisplay: inline-blockหรือเค้าโครงตาราง
ctf0

ตรวจสอบลิงค์นี้: vanseodesign.com/css/vertical-centering ;)
Jordi Castilla

@Vucko ใช่ - นั่นเป็นสิ่งที่จำเป็นเพราะนี่เป็นเพียงรูปแบบที่เรียบง่ายของรูปแบบที่ซับซ้อนมาก แต่ตำแหน่งที่แน่นอนใน divs ทั้งสองเป็นสิ่งสำคัญ
Vladimirs

@Vladimirs ฉันเท่านั้นที่สามารถคิดmargin-top: calc((56px - 16px) / 2)ที่56px - parent height, 16px - element height/font-size- JSFiddle
Vucko

คำตอบ:


332

ก่อนอื่นของบันทึกย่อทั้งหมดที่vertical-alignใช้กับเซลล์ตารางและองค์ประกอบระดับแบบอินไลน์เท่านั้น

มีสองวิธีในการบรรลุการจัดตำแหน่งแนวตั้งซึ่งอาจหรืออาจไม่ตรงกับความต้องการของคุณ อย่างไรก็ตามฉันจะแสดงสอง วิธีจากรายการโปรดของฉัน:

1. การใช้transformและtop

.valign {
    position: relative;
    top: 50%;
    transform: translateY(-50%);
    /* vendor prefixes omitted due to brevity */
}
<div style="position: absolute; left: 50px; top: 50px;">
    <div style="text-align: left; position: absolute;height: 56px;background-color: pink;">
        <div class="valign" style="background-color: lightblue;">test</div>
    </div>
</div>

จุดสำคัญคือว่าค่าร้อยละเมื่อtopเทียบกับheightบล็อกที่มี; ในขณะที่ค่าร้อยละtransformของ s จะสัมพันธ์กับขนาดของกล่องตัวเอง (กล่องขอบเขต)

หากคุณประสบปัญหาการแสดงผลแบบอักษร (ฟอนต์พร่ามัว) การแก้ไขคือการเพิ่มperspective(1px)ไปยังการtransformประกาศจึงกลายเป็น:

transform: perspective(1px) translateY(-50%);

มันเป็นมูลค่า noting CSS ที่transform ได้รับการสนับสนุนใน IE9 +

2. การใช้inline-blockองค์ประกอบ (หลอก)

ในวิธีนี้เรามีinline-blockองค์ประกอบพี่น้องสองตัวที่จัดเรียงในแนวตั้งตรงกลางโดยvertical-align: middleการประกาศ

หนึ่งในนั้นมีส่วนheightหนึ่ง100%ของแม่และอีกองค์ประกอบหนึ่งคือองค์ประกอบที่เราต้องการซึ่งเราต้องการจัดตำแหน่งตรงกลาง

.parent {
    text-align: left;
    position: absolute;
    height: 56px;
    background-color: pink;
    white-space: nowrap;
    font-size: 0; /* remove the gap between inline level elements */
}

.dummy-child { height: 100%; }

.valign {
    font-size: 16px; /* re-set the font-size */
}

.dummy-child, .valign {
    display: inline-block;
    vertical-align: middle;
}
<div style="position: absolute; left: 50px; top: 50px;">
    <div class="parent">
        <div class="dummy-child"></div>
        <div class="valign" style="background-color: lightblue;">test</div>
    </div>
</div>

สุดท้ายเราควรใช้หนึ่งในวิธีการที่ใช้ได้เพื่อลบช่องว่างระหว่างองค์ประกอบแบบอินไลน์ระดับ


ขอบคุณสำหรับเคล็ดลับที่มีประโยชน์นี้ มันใช้งานได้สำหรับโครงการของฉัน ผลงานที่ดี.
Sedat Kumcu

สำหรับvalignองค์ประกอบวิธีการแรกควรเป็นdisplay: block
Oleg

transform: translateY(-50%);ไม่เคยเห็นมาก่อน แต่มันใช้งานได้อย่างไร้ที่ติ โปรแกรมรักษาชีวิตจริง
Benny Bottema

55

ใช้สิ่งนี้:

.Absolute-Center {
    margin: auto;
    position: absolute;
    top: 0; left: 0; bottom: 0; right: 0;
}

อ้างอิงลิงค์นี้: https://www.smashingmagazine.com/2013/08/absolute-horizontal-vertical-centering-css/


นี่เป็นวิธีแก้ปัญหาหลักไม่ใช่เหรอ? ง่ายมากและใช้งานได้!
Mason

21
โปรดจำไว้ว่าheightต้องกำหนดคุณสมบัติ (ใน px, em ฯลฯ ) เพื่อให้สิ่งนี้ใช้งานได้
Vaidas

จะเกิดอะไรขึ้นถ้าฉันมี div หลายอันภายใน parent จะไม่ทั้งหมดถูกวางไว้ด้านบนของแต่ละอื่น ๆ ?
psykid

มันใช้งานไม่ได้หากมีเด็กอีกคนในระดับเดียวกันด้วย "absolute-center"
Pascut

18

ใช้ flex blox ใน div ที่อยู่ในตำแหน่งที่เหมาะสมเพื่อจัดเนื้อหาให้อยู่กึ่งกลาง

ดูตัวอย่างhttps://plnkr.co/edit/wJIX2NpbNhO34X68ZyoY?p=preview

.some-absolute-div {    
  display: -webkit-box;
  display: -webkit-flex;
  display: -moz-box;
  display: -moz-flex;
  display: -ms-flexbox;
  display: flex;

  -webkit-box-pack: center;
  -ms-flex-pack: center;
  -webkit-justify-content: center;
  -moz-justify-content: center;
  justify-content: center;

  -webkit-box-align: center;
  -ms-flex-align: center;
  -webkit-align-items: center;
  -moz-align-items: center;
  align-items: center;
}

11

จัดกึ่งกลางในแนวตั้งและแนวนอน:

.parent{
  height: 100%;
  position: absolute;
  width: 100%;
  top: 0;
  left: 0;
}
.c{
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  transform: translateY(-50%);
}

3

คุณอาจใช้display:table/table-cell;

.a{
   position: absolute; 
  left: 50px; 
  top: 50px;
  display:table;
}
.b{
  text-align: left; 
  display:table-cell;
  height: 56px;
  vertical-align: middle;
  background-color: pink;
}
.c {
  background-color: lightblue;
}
<div class="a">
  <div  class="b">
    <div class="c" >test</div>
  </div>
</div>


ขอบคุณตัวอย่างของคุณใช้งานได้ดี แต่.bขาดหายไปposition: absolute;ซึ่งเป็นสิ่งสำคัญที่จะต้องแสดงคุณสมบัติอื่น ๆ ซึ่งฉันไม่ได้รวมไว้เพื่อให้รหัสชัดเจนยิ่งขึ้น ฉันรู้ว่ามันไม่มีเหตุผลที่จะมีตารางเซลล์อยู่ในตำแหน่งที่แน่นอน แต่อาจมีวิธีอื่นที่จะช่วยให้สามารถรักษาposition: absolute;ทั้งใน.aและ.bคลาสได้?
วลาดิเมียร์

ถ้า a เป็นตำแหน่งที่แน่นอนและ b (เด็ก) ให้มันมีขนาด b คือตัวเองในตำแหน่งที่แน่นอนไปยังเนื้อหาที่เหลือ นอกเสียจากว่า a จะยังคงไม่ได้รับการยืนยันฉันไม่เข้าใจวัตถุประสงค์ของการอยู่ภายในแน่นอน
G-Cyrillus

1

นี่คือวิธีง่ายๆในการใช้วัตถุยอดนิยม

เช่น: หากขนาดองค์ประกอบที่แน่นอนคือ 60px

.absolute-element { 
    position:absolute; 
    height:60px; 
    top: calc(50% - 60px);
}

2
การใช้calcจะมีประโยชน์แม้ว่าควรtop: calc(50% - 30px)จะอยู่กึ่งกลางจริงๆ
brainbag

1

ทางออกที่ง่ายเพิ่มเติม

HTML:

<div id="d1">
    <div id="d2">
        Text
    </div>
</div>

CSS:

#d1{
    position:absolute;
    top:100px;left:100px;
}

#d2{
    border:1px solid black;
    height:50px; width:50px;
    display:table-cell;
    vertical-align:middle;
    text-align:center;  
}

0

โปรดตรวจสอบคำตอบนี้เพื่อแก้ไขปัญหาที่คล้ายกัน

นี่เป็นวิธีที่ง่ายที่สุดที่ฉันค้นพบ

https://stackoverflow.com/a/26079837/4593442

บันทึก. ฉันใช้จอแสดงผล: -webkit-flex; แทนการแสดงผล: ดิ้น สำหรับการทดสอบภายในซาฟารี

เชิงอรรถ. ฉันเป็นสามเณรเท่านั้นแบ่งปันความช่วยเหลือจากคนที่มีประสบการณ์ชัดเจน


0

คุณสามารถทำได้โดยใช้display:table;ใน div parent และย่อยdisplay: table-cell; vertical-align: middle;child

<div style="display:table;">
      <div style="text-align: left;  height: 56px;  background-color: pink; display: table-cell; vertical-align: middle;">
          <div style="background-color: lightblue; ">test</div>
      </div>
  </div>


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