บรรทัดสูงเป็นเปอร์เซ็นต์ไม่ทำงาน


87

ฉันมีปัญหาเกี่ยวกับความสูงของเส้นที่ไม่สามารถคาดเดาได้

รหัสต่อไปนี้จะจัดกึ่งกลางภาพภายใน div:

CSS

.bar {
    height: 800px;
    width: 100%;
    line-height:800px;
    background-color: #000;
    text-align: center; 
}

.bar img {
    vertical-align: middle;   
}

HTML

<div class="bar">
    <img src="http://27.media.tumblr.com/yHWA4oxH870ulxnoH7CkOSDR_500.jpg" alt="Foo Image" />
</div>

อย่างไรก็ตามหากฉันเปลี่ยนความสูงของเส้นเป็น 100% ความสูงของเส้นจะไม่มีผล (หรืออย่างน้อยก็ไม่กลายเป็น 100% ของ div)

ตัวอย่าง jsfiddle

มีใครรู้บ้างว่าฉันทำผิด?

คำตอบ:


195

line-height: 100%หมายถึง 100% ของขนาดตัวอักษรสำหรับองค์ประกอบนั้นไม่ใช่ 100% ของความสูง ในความเป็นจริงความสูงของบรรทัดอยู่เสมอเมื่อเทียบกับขนาดตัวอักษรสูงไม่เว้นแต่ค่าของมันใช้หน่วยของความยาวแน่นอน ( px, ptฯลฯ )


3
อา. มันเป็นความผิดพลาดโง่ ๆ ที่ทำให้ฉันได้รับเสมอ ขอบคุณ! ฉันจะยอมรับคำตอบของคุณเมื่อมันให้ฉัน
My Head Hurts

1
เห็นได้ชัดว่าผู้เขียน spec เข้าใจผิดคิดว่าไม่มีใครต้องการกำหนดขนาดตัวอักษร / ความสูงของเส้นให้สัมพันธ์กับความสูงขององค์ประกอบ ...
Andy

1
@Andy: (?) ข่าวดีก็คือว่านี้จะเร็ว ๆ นี้จะทำไปได้ผ่านการใช้ตัวแปรซ้อน รอเพียงไม่กี่ปี ...
BoltClock

@BoltClock อาเจ๋ง! มันคงจะดี. ขอบคุณสำหรับการให้ฉันรู้ว่า!
Andy

vh เป็นข้อยกเว้น ใน CSS3 หากคุณตั้งค่าเป็น 100vh มันจะใช้งานได้จริงตามที่นักพัฒนาบางคนต้องการ โปรดทราบว่ามันใช้ไม่ได้กับเบราว์เซอร์รุ่นเก่าที่ไม่รองรับ CSS3
Philll_t

99

ฉันรู้ว่าคำถามนี้เก่า แต่ฉันพบว่าสิ่งที่เป็นวิธีแก้ปัญหาที่สมบูรณ์แบบสำหรับฉัน

ฉันเพิ่ม css นี้ใน div ที่ฉันต้องการจัดกึ่งกลาง:

div:before {
  content: "";
  display: inline-block;
  height: 100%;
  vertical-align: middle;
}

วิธีนี้ใช้งานได้ทุกครั้งและสะอาด

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

@mixin vertical-align($align: middle) {
  &:before {
    content: "";
    display: inline-block;
    height: 100%;
    vertical-align: $align;
    // you can add font-size 0 here and restore in the children to prevent
    // the inline-block white-space to mess the width of your elements
    font-size: 0;
  }
  & > * {
    vertical-align: $align;
    // although you need to know the font-size, because "inherit" is 0
    font-size: 14px;
  }
}

คำอธิบายแบบเต็ม: div:beforeจะเพิ่มองค์ประกอบภายใน div แต่ก่อนลูก ๆ ของมัน เมื่อใช้:beforeหรือ:afterเราต้องใช้content:คำประกาศมิฉะนั้นจะไม่มีอะไรเกิดขึ้น แต่สำหรับวัตถุประสงค์ของเราเนื้อหาอาจว่างเปล่า จากนั้นเราจะบอกให้องค์ประกอบนั้นสูงเท่ากับพาเรนต์ตราบเท่าที่มีการกำหนดความสูงของพาเรนต์และองค์ประกอบนี้เป็นอินไลน์บล็อกเป็นอย่างน้อย vertical-alignกำหนดตำแหน่งแนวตั้งของตัวเองที่เกี่ยวข้องกับผู้ปกครองซึ่งต่างจากtext-alignที่ทำงานต่างกัน

การ@mixinประกาศมีไว้สำหรับผู้ใช้ sass และจะใช้ในลักษณะนี้:

div {
    @include vertical-align(middle)
}

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

ไม่ใช่คำตอบ แต่มีประโยชน์ที่สุด!
Alex

คุณช่วยอธิบายสิ่งที่เกิดขึ้นโดยละเอียดได้ไหม ฉันไม่ค่อยเข้าใจ
Valdrinium

1
@Valdrinit ฉันจะแก้ไขคำตอบพร้อมคำอธิบายเพิ่มเติม
santiago arizti

36

เมื่อคุณใช้เปอร์เซ็นต์เป็นความสูงของบรรทัดจะไม่ได้ขึ้นอยู่กับคอนเทนเนอร์ div แต่จะขึ้นอยู่กับขนาดแบบอักษร


22

line-height: 100% จะเป็นวิธีง่ายๆในการจัดองค์ประกอบกึ่งกลางแนวตั้งหากคำนวณโดยสัมพันธ์กับคอนเทนเนอร์ แต่จะง่ายเกินไปจึงไม่ได้ผล

ดังนั้นมันจึงเป็นอีกวิธีหนึ่งในการบอก line-height: 1em (ใช่มั้ย?)

อีกวิธีหนึ่งในการจัดองค์ประกอบในแนวตั้งคือ:

.container {
     position:relative;
}
.center {
     position:absolute;
     top:0; left:0; bottom:0; right:0;
     margin: auto;
     /* for horiz left-align, try "margin: auto auto auto 0" */
}

1
ไม่ได้ผลสำหรับฉัน ... ไม่แน่ใจว่าฉันขาดอะไรไป
clifgriffin

1
@clifgriffin ลองตั้งค่าความกว้างและความสูงคงที่ทั้งบนคอนเทนเนอร์และส่วนรอง "ตรงกลาง" ให้แน่ใจว่าเด็กเล็กกว่าคอนเทนเนอร์นั้น เด็กควรอยู่ตรงกลางในแนวนอนและแนวตั้งภายในภาชนะ
Rolf

23
มันจะง่ายเกินไปจึงใช้ไม่ได้ +1 :-)
elipoultorak

@clifgriffin ตรวจสอบให้แน่ใจว่าคอนเทนเนอร์มีความกว้างและความสูงที่ถูกต้องคุณสามารถจัดให้ทุกอย่างอยู่ตรงกลางใน div ขนาดเดียวกันได้ นี่คือการปรับเปลี่ยนที่ฉันต้องทำ
David Carrigan

@ user3576887 "มันจะง่ายเกินไปจึงใช้ไม่ได้" นั่นคือสาเหตุที่ทำให้ฉันลงคะแนน - มีเหตุผลที่ดีมากว่าทำไมมันถึงไม่ได้ผลอย่างที่คุณต้องการและนี่ไม่ควร ถูกบดบังด้วยจุดประสงค์เพื่อความบันเทิงการวิจารณ์หรืออะไรก็ตามที่ควรจะเป็น
TheThirdMan

11

อาจจะไม่สวย แต่ใช้งานได้และมีความหมาย

<div class="bar" style="display: table; text-align: center;">
    <img style="display: table-cell; vertical-align: middle;" src="http://27.media.tumblr.com/yHWA4oxH870ulxnoH7CkOSDR_500.jpg" alt="Foo Image" />
</div>

display: table-cell ให้องค์ประกอบที่มีความสามารถเฉพาะของตารางเพื่อจัดแนวตั้ง (อย่างน้อยที่สุดฉันคิดว่ามันไม่เหมือนใคร)


ขอบคุณสำหรับคำตอบฉันลองใช้รหัสของคุณแล้ว แต่ดูเหมือนจะไม่ได้ผลสำหรับฉัน
My Head Hurts

อืมแปลกไปหน่อย หากคุณสามารถโพสต์รหัสของคุณเพื่อให้ฉันได้ตรวจสอบอย่างละเอียดฉันอาจช่วยได้มากขึ้น
Johan Olsson

Olsson - ฉันเพิ่งวางรหัสของคุณลงใน JSFiddle และมันใช้ไม่ได้ ขอบคุณสำหรับข้อเสนอของความช่วยเหลือ - แต่ตอนนี้ฉันสามารถหลีกเลี่ยงการตั้งค่าความสูงของเส้นแบบสัมบูรณ์ได้ หากมีการเปลี่ยนแปลงเราจะตรวจสอบคำตอบของคุณต่อไป ขอขอบคุณอีกครั้งสำหรับความช่วยเหลือ!
My Head Hurts

6

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

line-height: 100vh;

รองรับเบราว์เซอร์


การใช้ vh ที่ถูกต้องตามกฎหมายหายากแทนที่จะเป็น%
cytsunny

1

โซลูชันนี้ใช้ได้กับ IE9 ขึ้นไป อันดับแรกเรากำหนดตำแหน่งสูงสุดของเด็กเป็น 50% (ตรงกลางของผู้ปกครอง) จากนั้นใช้translateกฎเลื่อนเด็กขึ้นครึ่งหนึ่งของความสูงจริง ประโยชน์หลักคือเราไม่จำเป็นต้องกำหนดความสูงของเด็กซึ่งจะคำนวณโดยเบราว์เซอร์แบบไดนามิก JSFiddle

.bar {
    height: 500px;
    text-align: center;
    background: green;
}
.bar img {
    position: relative;
    top: 50%;
    transform: translate(0, -50%);
}

1

วิธีการที่ทันสมัยกว่าคือการใช้ flexbox สำหรับสิ่งนี้มันง่ายกว่าและสะอาดกว่า อย่างไรก็ตาม flexbox เป็นกระบวนทัศน์ที่แตกต่างอย่างสิ้นเชิงจากสิ่งที่inline-block, floatหรือpositionเคยเป็น

ในการจัดแนวรายการภายใน.parentคุณทำ:

.parent {
  display: flex;
  align-items: center;
}

ที่เกี่ยวกับมัน บุตรหลานของflexผู้ปกครองจะถูกแปลงเป็นสิ่งของสำหรับเด็กที่ยืดหยุ่น

คุณควรอ่านเพิ่มเติมเกี่ยวกับ flexbox จุดเริ่มต้นที่ดีคือเอกสารโกงนี้: https://css-tricks.com/snippets/css/a-guide-to-flexbox/


0

คุณสามารถกำหนดความสูงของเส้นตามความสูงขององค์ประกอบนั้นได้ หากองค์ประกอบสูง 200px หมายความว่าคุณต้องตั้งค่าความสูงของเส้นเป็น 200px เพื่อให้ข้อความอยู่กึ่งกลาง

span {
  height: 200px;
  width: 200px; 
  border: 1px solid black;
  line-height: 200px; 
  display: block;
}
<span>Im vertically center</span>


0

นี่คือโซลูชันสมัยใหม่ที่คุณต้องตั้งค่า CSS ต่อไปนี้ในคอนเทนเนอร์ div หรือ div ด้านนอก

.outer-div {
  display: flex;
  justify-content: center;
  align-items: center; 
}

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

.inner-div {
    position: absolute;
    top: 50%; 
    left: 50%;
    transform: translate(-50%,-50%);
    text-align: center;
}

โปรดทราบว่าตำแหน่ง div ด้านนอกหรือคอนเทนเนอร์ควรสัมพันธ์กัน

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