วิธีการจัดกึ่งกลางเนื้อหาด้วยความสูงของตัวแปรภายใน div


158

เป็นวิธีที่ดีที่สุดในการจัดกึ่งกลางเนื้อหาของ div ในแนวตั้งเมื่อความสูงของเนื้อหาเป็นตัวแปรอะไร ในกรณีเฉพาะของฉันความสูงของ div container จะถูกแก้ไข แต่มันจะดีถ้ามีวิธีแก้ปัญหาที่จะทำงานในกรณีที่ container มีความสูงของตัวแปรเช่นกัน นอกจากนี้ฉันจะรักการแก้ปัญหาโดยไม่ใช้ CSS hacks และ / หรือมาร์กอัปที่ไม่ใช่ความหมายหรือน้อยมาก

ข้อความแสดงแทน


วิธีการในบทความนั้นแยกจากกันใน Safari (4.0.5): S

7
@ ripper234 ไม่ตรงตามคำถามนี้เกี่ยวกับความสูงแปรปรวน div
Rauli Rajande

9
นอกจากนี้คำถามนี้ถูกถามก่อน
Gui Imamura

คำตอบ:


147

เพียงเพิ่ม

position: relative;
top: 50%;
transform: translateY(-50%);

เพื่อ div ภายใน

สิ่งที่มันคือการย้ายเส้นขอบด้านบนของ div ภายในไปที่ความสูงครึ่งหนึ่งของ div ภายนอก ( top: 50%;) จากนั้น div ภายในจะสูงขึ้นครึ่งหนึ่ง ( transform: translateY(-50%)) นี้จะทำงานร่วมกับหรือposition: absoluterelative

โปรดทราบว่าtransformและtranslateมีคำนำหน้าผู้ขายซึ่งไม่รวมอยู่เพื่อความเรียบง่าย

Codepen: http://codepen.io/anon/pen/ZYprdb


6
เพิ่งสงสัยว่าทำไมการทำงานกับ Chrome และ Firefox แต่ไม่เหมาะสำหรับ Safari จากนั้นฉันสังเกตเห็นว่าtransformสิ่งที่เกี่ยวข้องส่วนใหญ่-webkit-นำหน้าอยู่และตอนนี้ใช้ได้ ดังนั้นอย่าลืมเพิ่ม-webkit-คำนำหน้าด้วย
miho

5
ใช้เครื่องมือเช่นgithub.com/postcss/autoprefixerเพื่อจัดการคำนำหน้าสำหรับคุณ
Jamie Chong

6
คำตอบนี้ควรจะอยู่ด้านบน
Jose Faeti

3
สิ่งนี้ควรมี upvotes มากขึ้น! ยังposition: absoluteไงมันก็ใช้ได้ด้วยใช่ไหม?
caw

4
วิธีนี้มีผลข้างเคียงที่โชคร้ายใน Chrome - หาก wrapper ของคุณมีจำนวนพิกเซลผิดปกติtranslateจะทำให้ทุกอย่างเบลอในขณะที่พยายามจัดการความสูง. 5px ในทุกสิ่ง
Keith

157

นี้น่าจะเป็นทางออกที่ดีที่สุดที่ฉันได้พบปัญหานี้ตราบใดที่เบราว์เซอร์ของคุณสนับสนุน::beforeองค์ประกอบหลอก: CSS-เคล็ดลับ: Centering ใน Unknown

ไม่ต้องใช้มาร์กอัปพิเศษและดูเหมือนว่าจะทำงานได้ดีมาก ฉันไม่สามารถใช้display: tableวิธีการนี้ได้เนื่องจากtableองค์ประกอบไม่ปฏิบัติตามmax-heightคุณสมบัติ

.block {
  height: 300px;
  text-align: center;
  background: #c0c0c0;
  border: #a0a0a0 solid 1px;
  margin: 20px;
}

.block::before {
  content: '';
  display: inline-block;
  height: 100%; 
  vertical-align: middle;
  margin-right: -0.25em; /* Adjusts for spacing */

  /* For visualization 
  background: #808080; width: 5px;
  */
}

.centered {
  display: inline-block;
  vertical-align: middle;
  width: 300px;
  padding: 10px 15px;
  border: #a0a0a0 solid 1px;
  background: #f5f5f5;
}
<div class="block">
    <div class="centered">
        <h1>Some text</h1>
        <p>But he stole up to us again, and suddenly clapping his hand on my
           shoulder, said&mdash;"Did ye see anything looking like men going
           towards that ship a while ago?"</p>
    </div>
</div>


3
ตอนนี้ - นั่นคือ - โซลูชั่น -BRILLIANT- ขอบคุณมากที่โพสต์ข้อความนี้!
ทรอยอัลฟอร์ด

เช่นเดียวกับคำตอบอื่น ๆ คำตอบนี้จะดีกว่ามากหากอธิบายวิธีการและรวมรหัสจากลิงก์
KatieK

3
+1, วิธีแก้ปัญหานี้ช่างฉลาดจริงๆ! Btw คุณสามารถเพิ่ม.block { white-space: nowrap; font-size: 0; line-height: 0; }และเว้นระยะขอบขวาติดลบในองค์ประกอบหลอกคุณเพียงแค่รีเซ็ต fs และ lh บน. ศูนย์กลาง ... เช่นนี้คุณมั่นใจได้ว่าองค์ประกอบจะถูกวางตำแหน่งอย่างถูกต้องแม้ว่าจะกว้างกว่าวิวพอร์ต (และไม่ ไม่จำเป็นต้องใช้ระยะขอบติดลบ imo เล็กน้อย)
Simon

@jessegavin - ในความคิดของคุณ ... กองซ้อนต่อไปนี้ขึ้นกับวิธีที่คุณระบุไว้อย่างไร: stackoverflow.com/questions/396145/…
pulkitsinghal

1
นอกจากนี้สิ่งนี้จะพังลงเมื่อคอนเทนเนอร์ภายนอก. block มีความสูงขั้นต่ำแทนความสูง
ลินคอล์น B

16

นี่คือสิ่งที่ฉันต้องทำหลายครั้งและวิธีแก้ปัญหาที่สอดคล้องกันยังคงต้องการให้คุณเพิ่มมาร์กอัปที่ไม่ใช่ความหมายและแฮ็กเฉพาะเบราว์เซอร์บางอย่าง เมื่อเราได้รับการสนับสนุนเบราว์เซอร์สำหรับ css 3 คุณจะได้รับการจัดกึ่งกลางแนวตั้งโดยไม่ทำบาป

สำหรับคำอธิบายที่ดีกว่าของเทคนิคคุณสามารถดูบทความที่ฉันดัดแปลงมาแต่โดยทั่วไปแล้วมันเกี่ยวข้องกับการเพิ่มองค์ประกอบพิเศษและใช้สไตล์ที่แตกต่างใน IE และเบราว์เซอร์ที่สนับสนุนposition:table\table-cellองค์ประกอบที่ไม่ใช่ตาราง

<div class="valign-outer">
    <div class="valign-middle">
        <div class="valign-inner">
            Excuse me. What did you sleep in your clothes again last night. Really. You're gonna be in the car with her. Hey, not too early I sleep in on Saturday. Oh, McFly, your shoe's untied. Don't be so gullible, McFly. You got the place fixed up nice, McFly. I have you're car towed all the way to your house and all you've got for me is light beer. What are you looking at, butthead. Say hi to your mom for me.
        </div>
    </div>
</div>

<style>
    /* Non-structural styling */
    .valign-outer { height: 400px; border: 1px solid red; }
    .valign-inner { border: 1px solid blue; }
</style>

<!--[if lte IE 7]>
<style>
    /* For IE7 and earlier */
    .valign-outer { position: relative; overflow: hidden; }
    .valign-middle { position: absolute; top: 50%; }
    .valign-inner { position: relative; top: -50% }
</style>
<![endif]-->
<!--[if gt IE 7]> -->
<style>
    /* For other browsers */
    .valign-outer { position: static; display: table; overflow: hidden; }
    .valign-middle { position: static; display: table-cell; vertical-align: middle; width: 100%; }
</style>

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

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

อัปเดต:เราเริ่มได้รับการสนับสนุนเบราว์เซอร์ที่ดีขึ้นสำหรับ CSS3 นำทั้งกล่องเฟล็กซ์และแปลงเป็นวิธีทางเลือกสำหรับการจัดกึ่งกลางแนวตั้ง (ท่ามกลางเอฟเฟกต์อื่น ๆ ) ดูคำถามอื่นสำหรับข้อมูลเพิ่มเติมเกี่ยวกับวิธีการที่ทันสมัย ​​แต่โปรดทราบว่าการสนับสนุนเบราว์เซอร์ยังคงเป็นร่างสำหรับ CSS3


ใช่ฉันพบบทความนั้นแล้ววันนี้และไม่สามารถใช้งานได้กับสถานการณ์เฉพาะของฉัน บางทีฉันอาจต้องการตรวจสอบเพิ่มเติม
jessegavin

บางทีคุณสามารถโพสต์รหัสที่คุณใช้ซึ่งไม่ได้ผล?
Chris Marasti-Georg

นี่ยังเป็นทางออกที่ดีที่สุดสำหรับปัญหานี้หรือไม่?
ripper234

ดูเหมือนว่าบทความนี้จะใช้งานไม่ได้กับ Chrome 23, Firefox 16 และ IE 9 คำตอบนี้น่าจะเป็นทางออกที่ดีกว่า
Fernando Correia

ไม่บทความนั้นยังคงทำงานใน Chrome และ Firefox ล่าสุด ณ วันที่ 24 กุมภาพันธ์ 2013
OMA

9

ด้วยการใช้ตัวเลือกลูกฉันได้รับคำตอบที่เหลือเชื่อของ Fadiด้านบนและต้มให้เป็นกฎ CSS เดียวที่ฉันสามารถใช้ได้ ตอนนี้สิ่งที่ฉันต้องทำคือเพิ่มcontentCenteredชื่อคลาสให้กับองค์ประกอบที่ฉันต้องการให้อยู่ตรงกลาง:

.contentCentered {
  text-align: center;
}

.contentCentered::before {
  content: '';
  display: inline-block;
  height: 100%; 
  vertical-align: middle;
  margin-right: -.25em; /* Adjusts for spacing */
}

.contentCentered > * {
  display: inline-block;
  vertical-align: middle;
}
<div class="contentCentered">
  <div>
    <h1>Some text</h1>
    <p>But he stole up to us again, and suddenly clapping his hand on my
      shoulder, said&mdash;"Did ye see anything looking like men going
      towards that ship a while ago?"</p>
  </div>
</div>

CodePen แยกแล้ว: http://codepen.io/dougli/pen/Eeysg


เย็น. ขอบคุณสำหรับการแบ่งปัน. ข้อควรระวังประการหนึ่งคือผู้*เลือกจะทำงานได้แย่กว่าคำตอบที่ยอมรับ อาจไม่เป็นปัญหา แต่ควรสังเกต stevesouders.com/blog/2009/06/18/simplifying-css-selectors
jessegavin

ขอบคุณ ใช่มันอาจจะทำงานแย่ลง แต่ทุกวันนี้กฎ CSS อาจไม่ส่งผลกระทบอะไรมากมาย เราสามารถปรับปรุงสิ่งนี้ได้โดยเลือก> divแทน calendar.perfplanet.com/2011/…
dougli

เรียบง่ายและยอดเยี่ยม ทำงานให้ฉันได้อย่างสมบูรณ์แบบ
Lovro

4

ผลลัพธ์ที่ดีที่สุดสำหรับฉันจนถึงตอนนี้:

div จะอยู่กึ่งกลาง:

position: absolute;
top: 50%;
transform: translateY(-50%);
margin: 0 auto;
right: 0;
left: 0;

ทำงานเหมือนจับใจ
m4heshd

3

คุณสามารถใช้มาร์จิ้นอัตโนมัติ ด้วยความยืดหยุ่นฝ่าย div ดูเหมือนจะอยู่กึ่งกลางในแนวตั้งด้วย

body,
html {
  height: 100%;
  margin: 0;
}
.site {
  height: 100%;
  display: flex;
}
.site .box {
  background: #0ff;
  max-width: 20vw;
  margin: auto;
}
<div class="site">
  <div class="box">
    <h1>blabla</h1>
    <p>blabla</p>
    <p>blablabla</p>
    <p>lbibdfvkdlvfdks</p>
  </div>
</div>

จอแสดงผล: เฟล็กยังคงเป็นคุณสมบัติทดลอง เบราว์เซอร์ยังไม่มีการสนับสนุนอย่างถูกต้อง
andreszs

1

สำหรับฉันวิธีที่ดีที่สุดในการทำเช่นนี้คือ:

.container{
  position: relative;
}

.element{
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
}

ข้อดีคือไม่ต้องทำให้ความสูงชัดเจน


0

นี่คือทางออกที่ยอดเยี่ยมของฉันสำหรับ a ที่divมีความสูงแบบไดนามิก (เปอร์เซ็นต์)

CSS

.vertical_placer{
  background:red;
  position:absolute; 
  height:43%; 
  width:100%;
  display: table;
}

.inner_placer{  
  display: table-cell;
  vertical-align: middle;
  text-align:center;
}

.inner_placer svg{
  position:relative;
  color:#fff;
  background:blue;
  width:30%;
  min-height:20px;
  max-height:60px;
  height:20%;
}

HTML

<div class="footer">
    <div class="vertical_placer">
        <div class="inner_placer">
            <svg> some Text here</svg>
        </div>
    </div>
</div>  

ลองด้วยตัวเอง


0

คุณสามารถใช้ flex display เช่นโค้ดด้านล่าง:

.example{
  background-color:red;
  height:90px;
  width:90px;
  display:flex;
  align-items:center; /*for vertically center*/
  justify-content:center; /*for horizontally center*/
}
<div class="example">
    <h6>Some text</h6>
</div>

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