ทำให้ div ในตำแหน่งที่แน่นอนขยายความสูง div parent


204

ที่คุณสามารถดูใน CSS ดังต่อไปนี้ผมต้องการที่จะวางตำแหน่งตัวเองก่อนchild2 child1นี่เป็นเพราะเว็บไซต์ที่ฉันกำลังพัฒนาควรทำงานบนอุปกรณ์มือถือซึ่งchild2ควรจะอยู่ด้านล่างเนื่องจากมีการนำทางที่ฉันต้องการด้านล่างเนื้อหาบนอุปกรณ์มือถือ - ทำไมถึงไม่ใช่มาสเตอร์เพจ 2 เพจ นี่เป็นเพียง 2 รายการเท่านั้นdivsที่มีการจัดตำแหน่งใหม่ใน HTML ทั้งหมดดังนั้นมาสเตอร์เพจ 2 รายการสำหรับการเปลี่ยนแปลงเล็กน้อยนี้จึงเป็น overkill

HTML:

<div id="parent">
    <div class="child1"></div>
    <div class="child2"></div>
</div>

CSS:

parent { position: relative; width: 100%; }
child1 { width: auto; margin-left: 160px; }
child2 { width: 145px; position: absolute; top: 0px; bottom: 0px; }

child2 มีความสูงแบบไดนามิกเนื่องจากไซต์ย่อยที่แตกต่างกันอาจมีรายการการนำทางไม่มากก็น้อย

ฉันรู้ว่าองค์ประกอบตำแหน่งที่แน่นอนจะถูกลบออกจากการไหลจึงไม่สนใจองค์ประกอบอื่น
ฉันพยายามตั้งoverflow:hidden;บน div แม่ clearfixแต่ที่ไม่ได้ช่วยเหลือค่าไม่

ทางเลือกสุดท้ายของฉันคือ JavaScript เพื่อเปลี่ยนตำแหน่งทั้งสองdivsแต่ตอนนี้ฉันจะลองดูว่ามีวิธีที่ไม่ใช้ JavaScript ในการทำเช่นนี้หรือไม่


3
ฉันไม่แน่ใจ 100% แต่ฉันคิดว่าคุณน่าจะต้องใช้โซลูชัน JS ซึ่งใช้ความสูงของ child2 และย้าย child1 ตามลำดับ
Billy Moat

2
สิ่งนี้สามารถทำได้โดยการตั้งค่าตำแหน่งของผู้ปกครองเป็นญาติและลูกที่จะแน่นอน
fungusanthrax

1
ดูวิธีแก้ปัญหานี้อาจช่วยได้
Az.Youness

คำตอบ:


152

คุณตอบคำถามด้วยตัวเอง: "ฉันรู้ว่าองค์ประกอบตำแหน่งที่แน่นอนจะถูกลบออกจากโฟลว์ดังนั้นองค์ประกอบอื่น ๆ จะถูกละเว้น" ดังนั้นคุณไม่สามารถตั้งค่าความสูงของผู้ปกครองตามองค์ประกอบตำแหน่งที่แน่นอน

คุณใช้ความสูงคงที่หรือคุณต้องเกี่ยวข้องกับ JS


1
ฉันทำเครื่องหมายสิ่งนี้เนื่องจากเป็นวิธีที่ถูกต้องแม้ว่าฉันจะพบวิธีแก้ไขปัญหาของฉันอีกวิธีหนึ่งซึ่งเป็นวิธีการวาง css ที่ต้องการในหน้าเว็บเฉพาะซึ่งต้องแตกต่างกัน (2 จาก 40 ในขณะนี้)

16

แม้ว่าการยืดไปยังองค์ประกอบด้วยposition: absoluteเป็นไปไม่ได้ แต่มักจะมีวิธีแก้ปัญหาที่คุณสามารถหลีกเลี่ยงการจัดตำแหน่งที่แน่นอนในขณะที่ได้รับผลกระทบเดียวกัน ดูซอที่แก้ปัญหานี้ในกรณีของคุณโดยเฉพาะhttp://jsfiddle.net/gS9q7/

เคล็ดลับคือการเรียงลำดับองค์ประกอบโดยการลอยทั้งสององค์ประกอบแรกไปทางขวาที่สองไปทางซ้ายดังนั้นที่สองปรากฏขึ้นก่อน

.child1 {
    width: calc(100% - 160px);
    float: right;
}
.child2 {
    width: 145px;
    float: left;
}

ในที่สุดเพิ่ม clearfix ให้กับผู้ปกครองและคุณทำเสร็จแล้ว (ดูซอสำหรับการแก้ปัญหาที่สมบูรณ์)

โดยทั่วไปตราบใดที่องค์ประกอบที่มีตำแหน่งสัมบูรณ์อยู่ด้านบนสุดขององค์ประกอบหลักโอกาสที่ดีที่คุณจะพบวิธีแก้ปัญหาโดยการลอยองค์ประกอบนั้น


10

Feeelaถูกต้องแต่คุณสามารถรับผู้ปกครองdivทำสัญญา / ขยายไปยังองค์ประกอบย่อยได้หากคุณกลับdivตำแหน่งของคุณดังนี้:

.parent{
    postion: absolute;
    /* position it in the browser using the `left`, `top` and `margin` 
       attributes */
}

.child{
    position: relative;
    height: 100%;
    width: 100%;

    overflow: hidden;
    /* to pad or move it around using `left` and `top` inside the parent */
}

สิ่งนี้น่าจะเหมาะกับคุณ


9

มีวิธีง่าย ๆ ในการแก้ปัญหานี้

คุณเพียงแค่ต้องทำซ้ำเนื้อหาของ child1 และ child2 ใน div ที่สัมพันธ์กับ display: none ใน parent div พูดลูก 1_1 และ child2_2 วาง child2_2 ไว้ด้านบนและ child1_1 ที่ด้านล่าง

เมื่อ jquery ของคุณ (หรืออะไรก็ตาม) เรียก div แน่นอนให้ตั้งค่า div ที่สัมพันธ์กัน (child1_1 หรือ child2_2) ด้วย display: block และทัศนวิสัย: hidden เด็กญาติจะยังคงมองไม่เห็น แต่จะทำให้ div ของผู้ปกครองสูงขึ้น


2
นี่ทำให้ฉันคิดในทิศทางที่ถูกต้อง ในการตั้งค่าเคสของฉันแสดง: ไม่มีในเนื้อหา "ขนาดตัวยึด" ทำให้ div ไม่ใช่ขนาด แต่ความทึบ: 0, ปรับขนาด div อย่างถูกต้องและไม่ต้องการ jquery เพิ่มเติมใด ๆ
edencorbin

วิธีที่ผมทำก็คือจะได้รับสอง divs ซ้ำกันคนแรกคือเนื้อหาที่มองเห็นด้วยกับตำแหน่งที่แน่นอนและคนที่สองเป็น div ที่มีการมองเห็นที่ซ่อนอยู่ที่ช่วยให้ div ผู้ปกครองที่มีความสูงที่ถูกต้องทั้งหมดทำงานได้ดี = D
Diogo การ์เซีย

4

ด้วย JavaScript ที่บริสุทธิ์คุณเพียงแค่ดึงความสูงของstatic positionองค์ประกอบลูกของคุณ.child1โดยใช้เมธอด getComputedStyle ()จากนั้นตั้งค่าที่ดึงค่าเป็นรายการpadding-topสำหรับเด็กคนเดียวกันโดยใช้คุณสมบัติHTMLElement.style


ตรวจสอบและเรียกใช้ข้อมูลโค้ดต่อไปนี้เพื่อเป็นตัวอย่างในทางปฏิบัติของสิ่งที่ฉันอธิบายข้างต้น:

/* JavaScript */

var child1 = document.querySelector(".child1");
var parent = document.getElementById("parent");

var childHeight = parseInt(window.getComputedStyle(child1).height) + "px";
child1.style.paddingTop = childHeight;
/* CSS */

#parent { position: relative; width: 100%; }
.child1 { width: auto; }
.child2 { width: 145px; position: absolute; top: 0px; bottom: 0px; }
html, body { width: 100%;height: 100%; margin: 0; padding: 0; }
<!-- HTML -->

<div id="parent">
    <div class="child1">STATIC</div>
    <div class="child2">ABSOLUTE</div>
</div>


2

ฉันมีปัญหาที่คล้ายกัน ในการแก้ปัญหานี้ (แทนที่จะคำนวณความสูงของ iframe โดยใช้เนื้อหาเอกสารหรือหน้าต่าง) ฉันสร้าง div ที่ล้อมเนื้อหาหน้าทั้งหมด (ตัวอย่างเช่น div ที่มี id = "page") จากนั้นฉันก็ใช้ความสูงของมัน


2

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

https://jsfiddle.net/tnhsaesop/vjftq198/3/

HTML:

<div class="parent">
  <div style="background-color:lightgrey;">
    <p>
      I stay on top on desktop and I'm on bottom on mobile
    </p>
  </div>
  <div style="background-color:grey;">
    <p>
      I stay on bottom on desktop and I'm on bottom on mobile
    </p>
  </div>
</div>

CSS:

.parent {
  display: flex;
  flex-direction: column;
}

@media (max-width: 768px) {
  .parent {
    flex-direction: column-reverse;
  }
}

1

ฉันหาวิธีแก้ปัญหาอื่นซึ่งฉันไม่รัก แต่ทำงานให้เสร็จ

ทำซ้ำองค์ประกอบของเด็กโดยทั่วไปในลักษณะที่ไม่สามารถมองเห็นรายการที่ซ้ำกันได้

<div id="parent">
    <div class="width-calc">
        <div class="child1"></div>
        <div class="child2"></div>
    </div>

    <div class="child1"></div>
    <div class="child2"></div>
</div>

CSS:

.width-calc {
    height: 0;
    overflow: hidden;
}

หากองค์ประกอบย่อยเหล่านั้นมีมาร์กอัปเล็กน้อยผลกระทบก็จะเล็ก


4
สิ่งนี้อาจทำให้เกิดปัญหากับการจัดอันดับของเครื่องมือค้นหา
mschadegg

1

"คุณใช้ความสูงคงที่หรือคุณจำเป็นต้องมีส่วนร่วมกับ JS"

นี่คือตัวอย่าง JS:

---------- ตัวอย่าง jQuery JS --------------------

    function findEnvelopSizeOfAbsolutelyPositionedChildren(containerSelector){
        var maxX = $(containerSelector).width(), maxY = $(containerSelector).height();

        $(containerSelector).children().each(function (i){
            if (maxX < parseInt($(this).css('left')) + $(this).width()){
                maxX = parseInt($(this).css('left')) + $(this).width();
            }
            if (maxY < parseInt($(this).css('top')) + $(this).height()){
                maxY = parseInt($(this).css('top')) + $(this).height();
            }
        });
        return {
            'width': maxX,
            'height': maxY
        }
    }

    var specBodySize = findEnvelopSizeOfAbsolutelyPositionedSubDivs("#SpecBody");
    $("#SpecBody").width(specBodySize.width);
    $("#SpecBody").height(specBodySize.height);

คำตอบนี้จะได้ประโยชน์จากคำอธิบายและทิศทางของโซลูชันที่นำเสนอที่ดีกว่า
DaniDev

1

มีแฮ็คที่ง่ายมากที่แก้ไขปัญหานี้

นี่คือ codesandbox ที่แสดงวิธีแก้ปัญหา: https://codesandbox.io/s/00w06z1n5l

HTML

<div id="parent">
  <div class="hack">
   <div class="child">
   </div>
  </div>
</div>

CSS

.parent { position: relative; width: 100%; }
.hack { position: absolute; left:0; right:0; top:0;}
.child { position: absolute; left: 0; right: 0; bottom:0; }

คุณสามารถเล่นกับการวางตำแหน่งของแฮ็ค div เพื่อส่งผลต่อตำแหน่งของเด็ก ๆ

นี่คือตัวอย่าง:

html {
  font-family: sans-serif;
  text-align: center;
}

.container {
  border: 2px solid gray;
  height: 400px;
  display: flex;
  flex-direction: column;
}

.stuff-the-middle {
  background: papayawhip
    url("https://camo.githubusercontent.com/6609e7239d46222bbcbd846155351a8ce06eb11f/687474703a2f2f692e696d6775722e636f6d2f4e577a764a6d6d2e706e67");
  flex: 1;
}

.parent {
  background: palevioletred;
  position: relative;
}

.hack {
  position: absolute;
  left: 0;
  top:0;
  right: 0;
}
.child {
  height: 40px;
  background: rgba(0, 0, 0, 0.5);
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
}
    <div class="container">
      <div class="stuff-the-middle">
        I have stuff annoyingly in th emiddle
      </div>
      <div class="parent">
        <div class="hack">
          <div class="child">
            I'm inside of my parent but absolutely on top
          </div>
        </div>
        I'm the parent
        <br /> You can modify my height
        <br /> and my child is always on top
        <br /> absolutely on top
        <br /> try removing this text
      </div>
    </div>


0

มีวิธีที่ดีกว่าในการทำเช่นนี้ในขณะนี้ คุณสามารถใช้คุณสมบัติด้านล่าง

    .my-element {
      position: absolute;
      bottom: 30px;
    }

5
สิ่งนี้จะใช้งานได้ก็ต่อเมื่อคุณทราบความสูงสุดท้ายของผู้ปกครองซึ่งคุณไม่ต้องการ
machineaddict

0

นี่คล้ายกับสิ่งที่ @ChrisC แนะนำ มันไม่ได้ใช้องค์ประกอบตำแหน่งที่แน่นอน แต่เป็นองค์ประกอบที่เกี่ยวข้อง อาจทำงานให้คุณได้

<div class="container">
  <div class="my-child"></div>
</div>

และ CSS ของคุณเช่นนี้:

.container{
    background-color: red;
    position: relative;
    border: 1px solid black;
    width: 100%;
}

.my-child{
    position: relative;
    top: 0;
    left: 100%;
    height: 100px;
    width: 100px;
    margin-left: -100px;
    background-color: blue;
}

https://jsfiddle.net/royriojas/dndjwa6t/


0

พิจารณาแนวทางถัดไป:

CSS:

.parent {
  height: 100%;
}
.parent:after {
  content: '';
  display: block;
}

นอกจากนี้เนื่องจากคุณพยายามเปลี่ยนตำแหน่ง div ให้พิจารณา css grid


-2

มุมมองที่แน่นอนวางตำแหน่งตัวเองกับบรรพบุรุษที่ใกล้ที่สุดที่ไม่ได้ตำแหน่งแบบคงที่ ( position: static) ดังนั้นหากคุณต้องการมุมมองที่แน่นอนในตำแหน่งกับผู้ปกครองที่กำหนดตั้งผู้ปกครองpositionเพื่อrelativeและเด็กpositionไปabsolute


-4

ลองสิ่งนี้มันได้ผลกับฉัน

.child {
    width: 100%;
    position: absolute;
    top: 0px;
    bottom: 0px;
    z-index: 1;
}

มันจะตั้งค่าความสูงของเด็กเป็นความสูงหลัก


ทางออกที่ดี!
Alexander Cherednichenko

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