ทำให้ div (ความสูง) ใช้ความสูงที่เหลือของพาเรนต์


107

http://jsfiddle.net/S8g4E/

ฉันมีตู้คอนเทนเนอร์divกับลูกสองคน ลูกคนแรกมีส่วนสูงที่กำหนด ฉันจะทำให้ลูกคนที่สองครอบครอง "พื้นที่ว่าง" ของภาชนะdivโดยไม่ให้ความสูงเฉพาะได้อย่างไร

ในตัวอย่างสีชมพูdivควรใช้พื้นที่สีขาวด้วย


คล้ายกับคำถามนี้: ทำอย่างไรให้ div ครอบครองส่วนสูงที่เหลืออยู่?

แต่ฉันไม่ต้องการที่จะให้ตำแหน่งที่แน่นอน


ฉันพยายามให้ลูกคนที่สองสูง 100% แต่ไม่ได้ผล: jsfiddle.net/S8g4E/1
Alvaro

คำตอบ:


156

การขยาย#downเด็กให้เต็มพื้นที่ที่เหลือ#containerสามารถทำได้หลายวิธีขึ้นอยู่กับการสนับสนุนเบราว์เซอร์ที่คุณต้องการบรรลุและ#upมีความสูงที่กำหนดไว้หรือไม่

ตัวอย่าง

กริด

gridเลย์เอาต์ของ CSS มีอีกทางเลือกหนึ่งแม้ว่าอาจจะไม่ตรงไปตรงมาเท่าโมเดล Flexbox อย่างไรก็ตามต้องมีการกำหนดสไตล์องค์ประกอบคอนเทนเนอร์เท่านั้น:

.container { display: grid; grid-template-rows: 100px }

grid-template-rowsกำหนดแถวแรกเป็นคงที่ 100px สูงและยังคงอยู่แถวโดยอัตโนมัติจะยืดไปเติมช่องว่างที่เหลืออยู่

ฉันค่อนข้างมั่นใจว่า IE11 ต้องการ-ms-คำนำหน้าดังนั้นอย่าลืมตรวจสอบการทำงานในเบราว์เซอร์ที่คุณต้องการรองรับ

Flexbox

ตอนนี้โมดูลเค้าโครงกล่องที่ยืดหยุ่นflexboxของ CSS3 ( )ได้รับการสนับสนุนอย่างดีและสามารถนำไปใช้งานได้ง่ายมาก เนื่องจากมีความยืดหยุ่นจึงใช้งานได้แม้#upไม่มีความสูงที่กำหนดไว้

#container { display: flex; flex-direction: column; }
#down { flex-grow: 1; }

สิ่งสำคัญคือต้องทราบว่าการรองรับ IE10 และ IE11 สำหรับคุณสมบัติ Flexbox บางอย่างอาจเป็นข้อบกพร่องและ IE9 หรือต่ำกว่านั้นไม่มีการรองรับเลย

ความสูงที่คำนวณได้

วิธีแก้ปัญหาง่ายๆอีกวิธีหนึ่งคือการใช้หน่วยฟังก์ชันCSS3 calcตามที่ Alvaro ชี้ให้เห็นในคำตอบของเขาแต่ต้องใช้ความสูงของลูกคนแรกเป็นค่าที่ทราบ:

#up { height: 100px; }
#down { height: calc( 100% - 100px ); }

ได้รับการสนับสนุนอย่างกว้างขวางโดยมีข้อยกเว้นที่โดดเด่นเพียงอย่างเดียวคือ <= IE8 หรือ Safari 5 (ไม่รองรับ) และ IE9 (รองรับบางส่วน) ปัญหาอื่น ๆ รวมถึงการใช้calcร่วมกับการแปลงร่างหรือbox-shadowดังนั้นอย่าลืมทดสอบในหลายเบราว์เซอร์หากเป็นเรื่องที่คุณกังวล

ทางเลือกอื่น ๆ

หากต้องการการสนับสนุนที่เก่ากว่าคุณสามารถเพิ่มheight:100%;เพื่อ#downทำให้ div สีชมพูเต็มความสูงได้โดยมีข้อแม้เดียว มันจะทำให้ภาชนะล้นเพราะ#upดันมันลง

ดังนั้นคุณสามารถเพิ่มลงoverflow: hidden;ในคอนเทนเนอร์เพื่อแก้ไขปัญหานั้นได้

อีกวิธีหนึ่งถ้าความสูง#upคงที่คุณสามารถวางตำแหน่งไว้ในคอนเทนเนอร์ได้อย่างแน่นอนและเพิ่มช่องว่าง#downภายใน

และอีกทางเลือกหนึ่งคือใช้การแสดงตาราง:

#container { width: 300px; height: 300px; border: 1px solid red; display: table;}
#up { background: green; display: table-row; height: 0; }
#down { background: pink; display: table-row;}​

4
ฉันต้องการ # ลงมี # ความสูงของตู้คอนเทนเนอร์ - # ความสูง สิ่งที่ซ่อนอยู่ล้นไม่ใช่สิ่งที่ฉันกำลังมองหา และไม่ต้องการใช้ตำแหน่งที่แน่นอน ขอบคุณ!
Alvaro

@Alvaro ฉันได้เพิ่มตัวเลือกอื่นโดยใช้การแสดงตาราง ข้อเสียตรงนี้คือความเข้ากันได้ ป.ล. องค์ประกอบที่อยู่ในตำแหน่งอย่างแน่นอนภายในคอนเทนเนอร์โดยให้position: relative;ตำแหน่งสัมพันธ์กับคอนเทนเนอร์ไม่ใช่หน้าต่าง ดังนั้นควรเป็นตัวเลือกที่ใช้ได้
ผู้ใช้

2
แถวตารางควรใช้งานได้สำหรับคุณโปรดดูjsFiddle นี้เพื่อพิสูจน์ วิธีการกำหนดตำแหน่งจะไม่สามารถให้ผลลัพธ์เดียวกันกับซอนี้ได้ดังนั้นเราจึงสามารถขูดออกจากรายการได้ (#down และ #container จะมีความสูงเท่ากันในสถานการณ์นั้น)
ผู้ใช้

3
คุณกำลังถามมาก @Alvaro CSS ไม่ใช่ภาษาสคริปต์ มันคำนวณสิ่งของไม่ได้ คุณติดอยู่กับภาพลวงตาหรือ js
Jezen Thomas

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

24

เป็นเวลาเกือบสองปีแล้วที่ฉันถามคำถามนี้ ฉันเพิ่งมาพร้อมกับ css calc () ที่ช่วยแก้ปัญหานี้ที่ฉันมีและคิดว่ามันจะดีที่จะเพิ่มในกรณีที่มีคนมีปัญหาเดียวกัน (โดยวิธีการที่ฉันใช้ตำแหน่งสัมบูรณ์)

http://jsfiddle.net/S8g4E/955/

นี่คือ css

#up { height:80px;}
#down {
    height: calc(100% - 80px);//The upper div needs to have a fixed height, 80px in this case.
}

และข้อมูลเพิ่มเติมได้ที่นี่: http://css-tricks.com/a-couple-of-use-cases-for-calc/

การสนับสนุนเบราว์เซอร์: http://caniuse.com/#feat=calc


1
ฉันก็ใช้ CSS3 เช่นกันcalcซึ่งการรองรับเบราว์เซอร์แบบกว้างไม่สำคัญเท่า (IE8 และต่ำกว่าและ Safari 5 ไม่รองรับ)
ผู้ใช้

3
มีวิธีใดบ้างที่จะทำเช่นเดียวกันกับ#upความสูงแบบไดนามิก
Adam Waite

@AdamWaite ด้วยความสูง #up แบบไดนามิกคุณจะต้องใช้โซลูชันโอเวอร์โฟลว์ที่อธิบายไว้ในคำตอบอื่น
ผู้ใช้

5

คำตอบของฉันใช้ CSS เท่านั้นและไม่ใช้ overflow: hidden หรือ display: table-row เด็กคนแรกต้องมีความสูงที่กำหนดจริง ๆ แต่ในคำถามของคุณคุณระบุว่ามีเพียงเด็กคนที่สองเท่านั้นที่ต้องการความสูงไม่ได้ระบุไว้ดังนั้นฉันเชื่อว่าคุณน่าจะยอมรับได้

html

<div id="container">
    <div id="up">Text<br />Text<br />Text<br /></div>
    <div id="down">Text<br />Text<br />Text<br /></div>
</div>

css

#container { width: 300px; height: 300px; border:1px solid red;}
#up { background: green; height: 63px; float:left; width: 100% }
#down { background:pink; padding-top: 63px; height: 100%; box-sizing: border-box; }

http://jsfiddle.net/S8g4E/288/


2

ตรวจสอบการสาธิต - http://jsfiddle.net/S8g4E/6/

ใช้ css -

#container { width: 300px; height: 300px; border:1px solid red; display: table;}
#up { background: green; display: table-row; }
#down { background:pink; display: table-row;}

คุณควรเพิ่มheight: 1pxเพื่อ#upให้แน่ใจว่าต้องใช้ความสูงขั้นต่ำ นี่คือการรองรับเบราว์เซอร์สำหรับdisplay: table: caniuse.com/css-table
สามสิบ

คุณช่วยแสดงวิธีแก้ปัญหานี้ให้สำเร็จได้อย่างไรในตัวอย่างที่ "ซับซ้อนกว่านี้" โปรด: jsfiddle.net/fyNX4ขอบคุณมาก
Alvaro

2

เว้นแต่ฉันกำลังเข้าใจผิดคุณก็สามารถเพิ่มheight: 100%;และการoverflow:hidden;#down

#down { 
    background:pink; 
    height:100%; 
    overflow:hidden;
}​

การสาธิตสด

แก้ไข: เนื่องจากคุณไม่ต้องการใช้overflow:hidden;คุณสามารถใช้display: table;สำหรับสถานการณ์นี้ได้ อย่างไรก็ตามไม่รองรับก่อน IE 8 ( display: table;การสนับสนุน )

#container { 
    width: 300px; 
    height: 300px; 
    border:1px solid red;
    display:table;
}

#up { 
    background: green;
    display:table-row;
    height:0; 
}

#down { 
    background:pink;
    display:table-row;
}​

การสาธิตสด

หมายเหตุ: คุณบอกว่าคุณต้องการให้#downความสูงเป็น#containerความสูงลบ#upความสูง display:table;แก้ปัญหาไม่ตรงกับที่และjsfiddle นี้จะวาดภาพที่สวยได้อย่างชัดเจน


1
ฉันไม่ต้องการให้ # ดาวน์เกิน # ความสูงของตู้คอนเทนเนอร์
Alvaro

ฉันเพิ่งสังเกตว่า คุณสามารถเพิ่มoverflow:hiddenเพื่อซ่อนเนื้อหาพิเศษได้
Josh Mein

1
ฉันจะคัดลอก / วางสิ่งที่ฉันพูดกับ MrSlayer: ฉันอยากให้ #down มี #container height - #up height สิ่งที่ซ่อนอยู่ล้นไม่ใช่สิ่งที่ฉันกำลังมองหา และไม่ต้องการใช้ตำแหน่งที่แน่นอน ขอบคุณ!
Alvaro

ปัญหาของสิ่งนี้คือถ้าคุณเปลี่ยนกลับทั้งสอง div ในตัวอย่างแล้ว div สีเขียวจะอยู่ด้านนอก
Ced

นี้ไม่ตอบคำถามเลย มันระบุว่า "เพื่อครอบครองความสูงที่เหลือทั้งหมด" แม้ว่าเหตุการณ์นี้จะใช้ความสูงที่เหลือทั้งหมด แต่ก็จะล้นออกมา
Giridhar Karnik

2

บทคัดย่อ

ฉันไม่พบคำตอบที่น่าพึงพอใจทั้งหมดดังนั้นฉันจึงต้องค้นหาด้วยตัวเอง

ความต้องการของฉัน:

  • องค์ประกอบควรใช้ว่าพื้นที่ที่เหลือทั้งเมื่อมันขนาดเนื้อหาเป็นขนาดเล็กหรือขนาดใหญ่กว่าขนาดของพื้นที่ที่เหลือ (ในกรณีที่สองเลื่อนควรจะแสดงให้เห็น );
  • วิธีการแก้ปัญหาควรจะทำงานเมื่อความสูงของพ่อแม่คือการคำนวณและไม่ระบุ ;
  • calc()ไม่ควรใช้เป็นองค์ประกอบที่เหลือไม่ควรรู้อะไรเกี่ยวกับขนาดองค์ประกอบอื่น
  • ควรใช้เทคนิคการจัดวางที่ทันสมัยและไม่เหมือนใครเช่นเฟล็กบ็อกซ์

การแก้ไขปัญหา

  • เปลี่ยนเป็น flexboxes พ่อแม่โดยตรงทั้งหมดที่มีความสูงที่คำนวณได้ (ถ้ามี)และพาเรนต์ถัดไปที่ระบุความสูง ;
  • ระบุflex-grow: 1ถึงผู้ปกครองโดยตรงทั้งหมดที่มีความสูงที่คำนวณได้ (ถ้ามี)และองค์ประกอบดังนั้นพวกเขาจะใช้พื้นที่ที่เหลือทั้งหมดเมื่อขนาดเนื้อหาขององค์ประกอบเล็กลง
  • ระบุflex-shrink: 0เพื่อรายการดิ้นทั้งหมดที่มีความสูงคงที่เพื่อให้พวกเขาจะไม่กลายเป็นขนาดเล็กเมื่อขนาดเนื้อหาองค์ประกอบที่มีขนาดใหญ่กว่าขนาดพื้นที่ที่เหลือ;
  • ระบุoverflow: hiddenถึงผู้ปกครองโดยตรงทั้งหมดที่มีส่วนสูงที่คำนวณได้ (ถ้ามี)เพื่อปิดใช้งานการเลื่อนและห้ามไม่ให้แสดงเนื้อหามากเกินไป
  • ระบุoverflow: autoเพื่อองค์ประกอบที่จะช่วยให้การเลื่อนภายในนั้น

JSFiddle (องค์ประกอบมีพ่อแม่โดยตรงที่มีความสูงที่คำนวณได้)

JSFiddle (กรณีง่ายๆ: ไม่มีผู้ปกครองโดยตรงที่มีความสูงที่คำนวณได้)


1

คุณสามารถใช้ลอยเพื่อดันเนื้อหาลง:

http://jsfiddle.net/S8g4E/5/

คุณมีคอนเทนเนอร์ขนาดคงที่:

#container {
    width: 300px; height: 300px;
}

เนื้อหาได้รับอนุญาตให้ไหลถัดจากโฟลต เว้นแต่เราจะตั้งค่า float เป็นแบบเต็มความกว้าง:

#up {
    float: left;
    width: 100%;
}

ในขณะที่#upและ#downแบ่งปันตำแหน่งบนสุด#downเนื้อหาจะเริ่มได้หลังจากด้านล่างสุดของการลอยเท่านั้น#up:

#down {
    height:100%;
}​

โปรดทราบว่า#upจริงๆแล้วครอบคลุมส่วนบนสุดของ#down: jsfiddle.net/thirtydot/S8g4E/9
สามสิบดอท

ใช่นั่นคือวิธีการทำงาน แต่ถ้า OP ไม่ต้องการขอบโค้งมนหรือความหรูหราอื่น ๆ#upก็น่าจะเป็นที่ยอมรับได้
biziclop

ทางออกนี้ใกล้เคียงแล้ว แต่ฉันต้องการ #down เพื่อให้มี #container height - #up height (ในโซลูชันของคุณ #down height = #container height) ขอบคุณ '
Alvaro

1
@Alvaro: ทำไมต้องเป็นแบบนั้น? วิธีนี้ดูเหมือนถูกต้องในกรณีส่วนใหญ่แม้ว่าจะเป็นเพียงภาพลวงตาก็ตาม
30

คำถามนี้เป็นตัวอย่างที่เรียบง่ายจากตัวอย่างที่ "ซับซ้อน" กว่านี้: jsfiddle.net/fyNX4 ไม่มีผลหรือไม่?
Alvaro

-3

ฉันไม่แน่ใจว่ามันสามารถทำได้ด้วย CSS เพียงอย่างเดียวเว้นแต่คุณจะพอใจที่จะแกล้งทำเป็นภาพลวงตา อาจใช้คำตอบของ Josh Mein และตั้งค่า#containerเป็นoverflow:hiddenที่จะ

สำหรับสิ่งที่คุ้มค่านี่คือโซลูชัน jQuery:

var contH = $('#container').height(),
upH = $('#up').height();
$('#down').css('height' , contH - upH);

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