CSS: การตั้งค่าความกว้าง / ความสูงเป็นเปอร์เซ็นต์ลบด้วยพิกเซล


479

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

ฉันมีคอนเทนเนอร์<div>ที่ฉันไม่ต้องการตั้งค่าความสูงสำหรับ (เพราะมันจะแตกต่างกันไปขึ้นอยู่กับว่ามันอยู่ที่ไหนในเว็บไซต์) และภายในมันเป็นส่วนหัว<div>และจากนั้นเป็นรายการที่ไม่เรียงลำดับทั้งหมดที่ใช้ CSS กับ พวกเขา

มันดูเหมือนเป็นอย่างมาก:

วิดเจ็ต

ฉันต้องการรายการที่ไม่ได้เรียงลำดับเพื่อใช้ห้องที่เหลือในภาชนะ<div>โดยรู้ว่าส่วนหัว<div>นั้น18pxสูง ฉันไม่ทราบวิธีระบุความสูงของรายการเป็น "ผลลัพธ์ของ100%ลบ18px"

ฉันเคยเห็นคำถามนี้ถามในบริบทอื่น ๆ อีกสองสามรายการใน SO แต่ฉันคิดว่ามันจะคุ้มค่าที่จะถามอีกครั้งสำหรับกรณีเฉพาะของฉัน ใครบ้างมีคำแนะนำในสถานการณ์นี้


6
ตั้งค่าระยะขอบ? __
kennytm

@ KennyTM ฉันคิดว่าคุณกำลังแนะนำให้ฉันใส่ส่วนต่างของราคาลงในรายการที่ไม่ได้เรียงลำดับพูด 17px แต่นี่เป็นการเพิ่มรายการทั้งหมดลง มันไม่ได้ทำให้มันหดตัวเพื่ออยู่ในภาชนะ โดยพื้นฐานแล้วความสูงในปัจจุบันยังคงอยู่ แต่มันก็ลดลงเพียง 17px นี่ไม่ได้แก้ปัญหาของฉัน แต่ฉันคิดว่ามันเป็นขั้นตอนในทิศทางที่ถูกต้องเพราะฉันเห็นวิธีการอื่น ๆ ทางออนไลน์ที่ใช้เทคนิคนี้
MegaMatt

ฉันเพิ่งแก้ไขปัญหานี้ในคำถามที่ฉันโพสต์ที่นี่ stackoverflow.com/a/10420387/340947
Steven Lu

คำตอบ:


895

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

height: calc(100% - 18px);

เป็นเรื่องที่ควรสังเกตว่าในขณะนี้มีบางเบราว์เซอร์ที่ไม่สนับสนุน CSS3 Calc () ฟังก์ชั่นมาตรฐานดังนั้นอาจจำเป็นต้องใช้เบราว์เซอร์เวอร์ชั่นเฉพาะของฟังก์ชั่นดังต่อไปนี้

/* Firefox */
height: -moz-calc(100% - 18px);
/* WebKit */
height: -webkit-calc(100% - 18px);
/* Opera */
height: -o-calc(100% - 18px);
/* Standard */
height: calc(100% - 18px);

5
ใช่ว่าเป็นเรื่องปกติในขณะนี้
Levi Botelho

1
เหมาะกับฉันใน IE10 และ Chrome 27 คุณเป็นฮีโร่ที่น่ากลัวของฉัน!
BrainSlugs83

3
@LeviBotelho ฉันไม่ดี ไม่มีพื้นที่ว่างรอบตัวดำเนินการ
ผู้ใช้

20
นอกจากนี้หากคุณใช้ Less คุณควรรวบรวมไฟล์ด้วยlessc --strict-math=onเพื่อไม่ให้ประเมินนิพจน์ภายในcalc- เป็นปัญหาที่ฉันเผชิญและใช้เวลามาก (ณ 2.0.0 น้อยกว่า)
Dmitry Wojciechowski

34
หมายเหตุว่าช่องว่างรอบเครื่องหมายลบไม่ได้ตัวเลือก: 100%-18px, 100%- 18pxและ100% -18pxไม่ได้ทำงานในเบราว์เซอร์ที่ผมทดสอบด้วย
nisetama

71

สำหรับวิธีการที่แตกต่างกันเล็กน้อยคุณสามารถใช้สิ่งนี้ในรายการ:

position: absolute;
top: 18px;
bottom: 0px;
width: 100%;

สิ่งนี้ทำงานได้ตราบใดที่คอนเทนเนอร์พาเรนต์มี position: relative;


1
ขอบคุณชาย คอนเทนเนอร์หลักกำลังposition: relative;สะดุดฉัน
gthmb

สำหรับผู้ที่อาจสงสัยเหมือนผม: ตำแหน่งที่จะต้องมีในภาชนะที่เด็กจะไม่สามารถabsolute relative
Greg

ดำเนินการต่อ (ขออภัย): อย่างไรก็ตามผู้ปกครองต้องการเพียงการวางตำแหน่ง (สามารถabsoluteเกินไป) และจำเป็นต้องตั้งค่าเป็นความสูง 100% เช่นกัน
เกร็ก

1
น่าเสียดายที่มันใช้งานไม่ได้กับ Safari iOS 8 (ผ่านการทดสอบ OK บน Android 4.1 เบราว์เซอร์หุ้นและมาตรฐาน FF 34) :-(
Greg

งานนี้อาจในบางกรณี แต่ยังอาจก่อให้เกิดปัญหาบางอย่างที่เป็นองค์ประกอบในตำแหน่งอย่างถูกลบออกจากการไหลปกติดูstackoverflow.com/a/12821537/4173303
Christophe Weis

26

ฉันใช้ Jquery สำหรับสิ่งนี้

function setSizes() {
   var containerHeight = $("#listContainer").height();
   $("#myList").height(containerHeight - 18);
}

จากนั้นฉันผูกหน้าต่างปรับขนาดเพื่อคำนวณใหม่เมื่อใดก็ตามที่หน้าต่างเบราว์เซอร์ถูกปรับขนาด (หากขนาดของคอนเทนเนอร์เปลี่ยนไปด้วยการปรับขนาดหน้าต่าง)

$(window).resize(function() { setSizes(); });

12
@puffpio แน่นอน JS เป็นวิธีที่จะทำให้สำเร็จเป็นกรณี ๆ ไป แต่อย่างที่ฉันบอกฉันพยายามสร้าง CSS ทั่วไปเพื่อนำไปใช้กับหลาย ๆ หน้า (ซึ่งสืบทอดมาจากหน้าต้นแบบโดยบังเอิญ) ดังนั้นฉันไม่ต้องการใช้ JS แต่ขอบคุณสำหรับคำตอบ
MegaMatt

7
อย่าใส่สไตล์ของคุณไว้ใน JavaScript
Greg

8
@ รวมแล้วมันจะช่วยได้ถ้า CSS มีคุณสมบัติที่มีประโยชน์มากกว่านี้ บางสิ่งที่คุณต้องทำเพื่อแฮ็กก็ไร้สาระ
โจนาธาน

1
@puffpio Nice ทางออกแน่นอน แต่การผูกเหตุการณ์บนหน้าต่างไม่ใช่ทางออกที่ดีสำหรับฉัน หากหน้าของฉันมีองค์ประกอบดังกล่าว 3-4 ชิ้นขึ้นไปฉันต้องอัปเดตความสูงและความกว้างของแต่ละองค์ประกอบในหน้าต่างปรับขนาดตัวจัดการ นี่จะช้ากว่าโซลูชัน CSS เล็กน้อย
sachinjain024

1
"อย่าใส่ xyz ของคุณไว้ใน JavaScript" ก็เหมือนกับการพูดว่า "ไม่รองรับ 80% ของตลาดเบราว์เซอร์"
Beejor

16

อย่ากำหนดความสูงเป็นเปอร์เซ็นต์เพียงตั้งค่าtop=0และbottom=0เช่นนี้:

#div {
   top: 0; bottom: 0;
   position: absolute;
   width: 100%;
}

คุณช่วยอธิบายได้ไหมว่าทำไมไม่ตั้งความสูงเป็นเปอร์เซ็นต์
Shrikant Sharat

@ShrikantSharat นี่เป็นส่วนหนึ่งของข้อกำหนดการจัดรูปแบบภาพสำหรับองค์ประกอบที่จัดวางอย่างแน่นอน โซลูชันนี้ใช้ประโยชน์จากความเป็นไปได้ที่ 5 '' ความสูง 'คือ' อัตโนมัติ '' บนสุด 'และ' ด้านล่าง 'ไม่ใช่' อัตโนมัติ 'จากนั้นตั้งค่า' อัตโนมัติ 'สำหรับ' ขอบบน 'และ' ขอบล่าง ' ถึง 0 และแก้ปัญหาสำหรับ 'height' " เบราว์เซอร์สามารถคำนวณความสูงขององค์ประกอบเนื่องจากรู้ว่าไกลจากด้านบนและด้านล่างของแม่มันจะต้อง
Ross Allen

ดูเหมือนจะใช้งานไม่ได้อย่างน้อยใน Firefox ถึงแม้จะมีองค์ประกอบที่พ่อแม่ตั้งทั้งหมดและheight:100% display:blockมิฉะนั้นมันจะเป็นทางออกที่หรูหรามาก ที่น่าสนใจคือmargin:autoยังไม่สามารถจัดวางวัตถุที่มีความกว้างคงที่ในแนวตั้งแม้ว่ามันจะทำงานได้ดีในแนวนอน
Beejor

8

การสันนิษฐานความสูงส่วนหัว 17px

รายการ css:

height: 100%;
padding-top: 17px;

ส่วนหัว CSS:

height: 17px;
float: left;
width: 100%;

ใช่นั่นคือสิ่งที่ฉันได้รับ
dclowd9901

1
มันไม่ได้ผลเท่าที่ฉันหวังไว้ รายการที่ไม่เรียงลำดับของฉันกำลังเริ่มต้นใต้ div ส่วนหัวนั้น div ส่วนหัวใช้พื้นที่ในคอนเทนเนอร์ดังนั้นการวาง padding-top ของ 17px ในรายการกำลังจะกดลง 17px จากตำแหน่งที่มันอยู่ในรูปภาพด้านบนไม่ใช่ 17px จากด้านบนของ div div นี่คือรูปของสิ่งที่ฉันได้รับด้วย CSS ที่กำหนดในคำตอบข้างต้น: i41.tinypic.com/mcuk1x.jpg ฉันขอขอบคุณความพยายาม แต่และหากมีบางสิ่งที่คุณคิดว่าฉันขาดหายไปโปรดแจ้งให้เราทราบ Btw ฉันมีมากเกินไป: อัตโนมัติในรายการที่ไม่ได้เรียงลำดับเช่นกัน
MegaMatt

2
มันจะง่ายกว่าการแก้ไขปัญหานี้ถ้าคุณโพสต์ css จริงเพื่อให้เราเห็นว่าการโต้ตอบเกิดขึ้นจริง อีกอย่างที่คุณอาจลองก็คือลบขอบบนสุดของ ul ul { margin-top: -17px; }
ghoppe

7
  1. ใช้ระยะขอบติดลบบนองค์ประกอบที่คุณต้องการลบพิกเซล (องค์ประกอบที่ต้องการ)
  2. ทำoverflow:hidden;ในองค์ประกอบที่มี
  3. สลับไปoverflow:auto;ที่องค์ประกอบที่ต้องการ

มันใช้งานได้สำหรับฉัน!


3
สิ่งนี้ได้ผลเหมือนเป็นเสน่ห์สำหรับฉัน (ฉันไม่จำเป็นต้องเปลี่ยนโอเวอร์โฟลว์) ทางออกที่ดีขอบคุณ!
Aaj

1
สุดยอดไปเลย! สนุกกับการเรียนรู้เกี่ยวกับโซลูชัน "CSS calc" ยอดนิยม แต่วิธีนี้ง่ายกว่ามากและรองรับเบราว์เซอร์ที่กว้างขึ้น อัตรากำไรขั้นต้นติดลบในที่สมบูรณ์แบบ!
Simon Steinberger

นี่เป็นโซลูชันที่หรูหราและเข้ากันได้ดีมาก ข้อเสียที่สำคัญคือองค์ประกอบจะต้องมีความสูงคงที่ มิฉะนั้นคุณจะต้องใช้ JS หรือcalc()ให้อยู่กึ่งกลางที่รันไทม์ แต่สำหรับหลาย ๆ กรณีนี่ไม่ควรเป็นปัญหา สิ่งที่ควรทราบอีกอย่างคือการใช้ค่าลบจำนวนมากสำหรับระยะขอบการแพ็ดและออฟเซ็ตอาจทำให้เกิดความสับสนเมื่อทำการดีบั๊กโค้ดในภายหลังดังนั้นพยายามทำให้สิ่งต่าง ๆ ง่ายขึ้น
Beejor

5

ลองปรับขนาดกล่อง สำหรับรายการ:

height: 100%;
/* Presuming 10px header height */
padding-top: 10px;
/* Firefox */
-moz-box-sizing: border-box;
/* WebKit */
-webkit-box-sizing: border-box;
/* Standard */
box-sizing: border-box;

สำหรับส่วนหัว:

position: absolute;
left: 0;
top: 0;
height: 10px;

แน่นอนคอนเทนเนอร์หลักควรมีลักษณะดังนี้:

position: relative;

3

อีกวิธีหนึ่งที่จะบรรลุเป้าหมายเดียวกัน: กล่องดิ้น ทำให้คอนเทนเนอร์เป็นกล่องเฟล็กซ์แบบคอลัมน์จากนั้นคุณมีอิสระเต็มที่ที่จะอนุญาตให้องค์ประกอบบางอย่างมีขนาดคงที่ (พฤติกรรมเริ่มต้น) หรือเพื่อเติม / ย่อขนาดลงสู่พื้นที่คอนเทนเนอร์ (ด้วย flex-grow: 1 และ flex- หดตัว: 1)

#wrap {        
  display:flex;
  flex-direction:column;
}
.extendOrShrink {
  flex-shrink:1;
  flex-grow:1;
  overflow:auto;
}

ดูhttps://jsfiddle.net/2Lmodwxk/ (ลองขยายหรือลดหน้าต่างเพื่อสังเกตเห็นผลกระทบ)

หมายเหตุ: คุณสามารถใช้คุณสมบัติชวเลขได้:

   flex:1 1 auto;

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

2

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

ด้านล่างฉันสร้างตัวอย่างง่ายๆที่แสดงสิ่งที่เราทำลงไปซึ่งดูเหมือนว่าจะทำงานได้ดีสำหรับสถานการณ์ของเราและควรเข้ากันได้กับเบราว์เซอร์ส่วนใหญ่

ในองค์ประกอบหน้าต่างของเราเราเพิ่มระยะขอบ 20px ซึ่งก่อให้เกิดการวางตำแหน่งสัมพันธ์กับองค์ประกอบอื่น ๆ บนหน้าจอ แต่ไม่ได้มีส่วนร่วมกับ "ขนาด" ของหน้าต่าง จากนั้นส่วนหัวของหน้าต่างจะถูกจัดตำแหน่งอย่างแน่นอน (ซึ่งจะลบออกจากการไหลขององค์ประกอบอื่น ๆ ดังนั้นจึงไม่ทำให้องค์ประกอบอื่น ๆ เช่นรายการที่ไม่เรียงลำดับจะถูกเลื่อน) และด้านบนของมันอยู่ในตำแหน่ง -20px ซึ่งวางส่วนหัวไว้ภายในระยะขอบ ของหน้าต่าง ในที่สุดองค์ประกอบ ul ของเราจะถูกเพิ่มเข้าไปในหน้าต่างและความสูงสามารถตั้งค่าเป็น 100% ซึ่งจะทำให้องค์ประกอบนั้นเต็มส่วนของหน้าต่าง (ไม่รวมระยะขอบ)

*,*:before,*:after
{
  box-sizing: border-box;
}

.window
{
  position: relative;
  top: 20px;
  left: 50px;
  margin-top: 20px;
  width: 150px;
  height: 150px;
}

.window-header
{
  position: absolute;
  top: -20px;
  height: 20px;
  border: 2px solid black;
  width: 100%;
}

ul
{
  border: 5px dashed gray;
  height: 100%;
}
<div class="window">
  <div class="window-header">Hey this is a header</div>
  <ul>
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
    <li>Item 4</li>
    <li>Item 5</li>
  </ul>
</div>


1

ขอบคุณฉันแก้ปัญหาด้วยความช่วยเหลือของคุณปรับแต่งเล็กน้อยตั้งแต่ฉันต้องการ div ความกว้าง 100% ความสูง 100% (ความสูงน้อยกว่าของแถบด้านล่าง) และไม่มีการเลื่อนบนร่างกาย (โดยไม่แฮ็ค / ซ่อนแถบเลื่อน)

สำหรับ CSS:

 html{
  width:100%;height:100%;margin:0px;border:0px;padding:0px;
 }
 body{
  position:relative;width:100%;height:100%;margin:0px;border:0px;padding:0px;
 }
 div.adjusted{
  position:absolute;width:auto;height:auto;left:0px;right:0px;top:0px;bottom:36px;margin:0px;border:0px;padding:0px;
 }
 div.the_bottom_bar{
  width:100%;height:31px;margin:0px;border:0px;padding:0px;
}

สำหรับ HTML:

<body>
<div class="adjusted">
 // My elements that go on dynamic size area
 <div class="the_bottom_bar">
  // My elements that goes on bottom bar (fixed heigh of 31 pixels)
 </div>  
</div>  

นั่นเป็นกลอุบายใช่แล้วฉันใส่ค่ายิ่งน้อยลงบน div.adjusted สำหรับด้านล่างมากกว่าสำหรับความสูงของแถบด้านล่างอื่นแถบเลื่อนแนวตั้งปรากฏขึ้นฉันปรับให้เป็นค่าที่ใกล้ที่สุด

ความแตกต่างนั้นเป็นเพราะองค์ประกอบหนึ่งในพื้นที่แบบไดนามิกกำลังเพิ่มรูก้นพิเศษที่ฉันไม่ทราบวิธีกำจัด ... มันเป็นแท็กวิดีโอ (HTML5) โปรดทราบว่าฉันใส่แท็กวิดีโอนั้นด้วย CSS นี้ ( ดังนั้นจึงไม่มีเหตุผลที่จะทำให้รูก้น แต่มัน):

 video{
  width:100%;height:100%;margin:0px;border:0px;padding:0px;
 }

The objetive: มีวิดีโอที่ใช้เบราว์เซอร์ 100% (และปรับขนาดแบบไดนามิกเมื่อเบราว์เซอร์ถูกปรับขนาด แต่ไม่มีการเปลี่ยนแปลงอัตราส่วนภาพ) ลดช่องว่างด้านล่างที่ฉันใช้สำหรับ div ที่มีข้อความปุ่ม ฯลฯ (และตัวตรวจสอบความถูกต้อง) แน่นอน w3c & css)

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

 video{
  display:block;width:100%;height:100%;margin:0px;border:0px;padding:0px;
 }

หมายเหตุdisplay:block;เกี่ยวกับแท็กวิดีโอ


0

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

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