CSS: จะวางตำแหน่งสององค์ประกอบบนกันและกันโดยไม่ระบุความสูงได้อย่างไร


103

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

ขอบด้านซ้ายบนของ.layer2ควรชิดขอบซ้ายบนของlayer1

<!-- HTML -->
<div class="container_row">
    <div class="layer1">
        Lorem ipsum...
    </div>
    <div class="layer2">
        More lorem ipsum...
    </div>
</div>
<div class="container_row">
    ...same HTML as above. This one should never overlap the .container_row above.
</div>

/* CSS */
.container_row {}

.layer1 {
    position:absolute;
    z-index: 1;
}

.layer2 {
    position:absolute;
    z-index: 2;
}

1
position: absoluteไม่ใช่สไตล์ที่เหมาะสมที่จะใช้
BoltClock

ใช่position:absoluteรู้สึกไม่ถูกต้อง สไตล์ที่ใช่จะเป็นอย่างไร?
Andrew

ทำที่.layer1และ.layer2องค์ประกอบที่มีขนาดที่รู้จักกัน?
สั้นเกินไป

ไม่พวกเขายังมีขนาดที่ไม่รู้จัก
Andrew

คำตอบ:


83

ก่อนอื่นคุณควรรวมตำแหน่งในองค์ประกอบที่แน่นอนไม่เช่นนั้นคุณจะเจอพฤติกรรมแปลก ๆ และสับสน คุณอาจต้องการเพิ่มลงtop: 0; left: 0ใน CSS สำหรับองค์ประกอบทั้งสองตำแหน่งของคุณ นอกจากนี้คุณจะต้องมีposition: relativeใน.container_rowกรณีที่คุณต้องการให้องค์ประกอบที่อยู่ในตำแหน่งที่แน่นอนอยู่ในตำแหน่งที่เกี่ยวข้องกับระดับบนสุดแทนที่จะเป็นเนื้อหาของเอกสาร :

ถ้าองค์ประกอบมี 'position: absolute' บล็อกที่มีจะถูกกำหนดโดยบรรพบุรุษที่ใกล้ที่สุดโดยมี 'position' เป็น 'absolute', 'relative' หรือ 'fixed' ...

ปัญหาของคุณคือการposition: absoluteลบองค์ประกอบออกจากโฟลว์ปกติ :

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

ซึ่งหมายความว่าองค์ประกอบที่อยู่ในตำแหน่งที่แน่นอนจะไม่มีผลกระทบใด ๆ กับขนาดขององค์ประกอบหลักและองค์ประกอบแรกของคุณ<div class="container_row">จะมีความสูงเป็นศูนย์

ดังนั้นคุณจึงไม่สามารถทำสิ่งที่คุณกำลังพยายามทำกับองค์ประกอบที่อยู่ในตำแหน่งที่แน่นอนได้เว้นแต่คุณจะรู้ว่าพวกมันจะสูงแค่ไหน (หรือคุณสามารถระบุความสูงได้ในทางเดียวกัน) หากคุณสามารถระบุความสูงได้คุณสามารถวางความสูงเท่ากัน.container_rowและทุกอย่างจะเรียงกัน คุณยังสามารถใส่margin-topวินาที.container_rowเพื่อออกจากที่ว่างสำหรับองค์ประกอบที่อยู่ในตำแหน่งที่แน่นอน ตัวอย่างเช่น:

http://jsfiddle.net/ambiguous/zVBDc/


คำตอบที่ดีขอบคุณ! ฉันเดาว่าฉันอาจต้องหาความสูงแบบไดนามิกโดยใช้จาวาสคริปต์ ฉันแค่หวังว่ามันจะไม่ต้องมาถึงจุดนั้น = [
Andrew

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

1
ไม่position: absoluteจำเป็น โปรดตรวจสอบ: stackoverflow.com/a/51949049/1736186
แทน

73

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

โปรดตรวจสอบตัวอย่างด้านล่างตาม HTML ของคุณ ฉันเพิ่มเฉพาะ<span>และบางสีเพื่อให้คุณเห็นผลลัพธ์

คุณยังสามารถเปลี่ยนz-indexองค์ประกอบที่สืบต่อกันมาได้อย่างง่ายดายเพื่อปรับเปลี่ยนการมองเห็น (อันไหนควรอยู่ด้านบน)

.container_row{
  display: grid;
}

.layer1, .layer2{
  grid-column: 1;
  grid-row: 1;
}

.layer1 span{
  color: #fff;
  background: #000cf6;
}

.layer2{
  background: rgba(255, 0, 0, 0.4);
}
<div class="container_row">
    <div class="layer1">
        <span>Lorem ipsum...<br>Test test</span>
    </div>
    <div class="layer2">
        More lorem ipsum...
    </div>
</div>
<div class="container_row">
    ...same HTML as above. This one should never overlap the .container_row above.
</div>


11
ดี. แต่เพื่อความยุติธรรมdisplay: gridไม่ได้มีอยู่เมื่อเจ็ดปีก่อน :)
สั้นเกินไป

มีคำตอบด้านล่างเขียนโดย @Cornelius เขาใช้flexซึ่งมีการรองรับเบราว์เซอร์ที่ดีขึ้นมากในปัจจุบัน
Oleg Cherr

@muistooshort แต่ตอนนี้มีอยู่แล้วและคำถามนี้มีคนดูเยอะมาก
boroboris

@boroboris นั่นเป็นเหตุผลว่าทำไมหนึ่งในการโหวตถึงเป็นของฉัน
สั้นเกินไป

20

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

ฉันมีสององค์ประกอบที่มีขนาดเท่ากันและต้องการวางซ้อนกัน เนื่องจากแต่ละชิ้นมีขนาดเท่ากันสิ่งที่ฉันทำได้คือทำ

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

เฉพาะองค์ประกอบสุดท้าย วิธีนี้จะแทรกองค์ประกอบแรกอย่างถูกต้อง "ดัน" ความสูงของพ่อแม่และองค์ประกอบที่สองจะอยู่ด้านบน

หวังว่านี่จะช่วยให้ผู้อื่นพยายามซ้อนองค์ประกอบ 2+ ที่มีความสูง (ไม่ทราบ) เท่ากัน


1
หมายเหตุ: ด้วยวิธีนี้คุณจะยังคงจำเป็นต้องรู้ที่เป็นองค์ประกอบสูงหนึ่งเพื่อให้คุณสามารถอื่น ๆหนึ่ง position: aboslute
Alec

12

นี่คืออีกวิธีหนึ่งโดยใช้ display: flex แทน position: absolute หรือ display: grid

.container_row{
  display: flex;
}

.layer1 {
  width: 100%;
  background-color: rgba(255,0,0,0.5);  // red
}

.layer2{
  width: 100%;
  margin-left: -100%;
  background-color: rgba(0,0,255,0.5);  // blue
}
<div class="container_row">
    <div class="layer1">
        <span>Lorem ipsum...</span>
    </div>
    <div class="layer2">
        More lorem ipsum...
    </div>
</div>
<div class="container_row">
    ...same HTML as above. This one should never overlap the .container_row above.
</div>


ทางออกที่ดี ขอบคุณ!
Oleg Cherr

5

ฉันต้องตั้งค่า

Container_height = Element1_height = Element2_height

.Container {
    position: relative;
}

.ElementOne, .Container ,.ElementTwo{
    width: 283px;
    height: 71px;
}

.ElementOne {
    position:absolute;
}

.ElementTwo{
    position:absolute;
}

การใช้งานสามารถใช้ z-index เพื่อกำหนดว่าจะให้ตัวไหนอยู่ด้านบน


4

นี่คือ css ที่ใช้ซ้ำได้ซึ่งจะรักษาความสูงของแต่ละองค์ประกอบโดยไม่ต้องใช้position: absolute:

.stack {
    display: grid;
}
.stack > * {
    grid-row: 1;
    grid-column: 1;
}

องค์ประกอบแรกในคุณstackคือพื้นหลังและองค์ประกอบที่สองคือพื้นหน้า


2

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


1

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

คุณยังสามารถเพิ่มหุ่นจำลองdivลงในคอนเทนเนอร์และตั้งค่าบางอย่างเช่นpadding-top: 56.25%เพื่อให้องค์ประกอบจำลองมีความสูงซึ่งเป็นสัดส่วนของความกว้างของคอนเทนเนอร์ สิ่งนี้จะดันคอนเทนเนอร์ออกมาและให้อัตราส่วนภาพในกรณีนี้คือ 16: 9 (56.25%)

การเว้นระยะห่างและระยะขอบใช้เปอร์เซ็นต์ของความกว้างนั่นคือเคล็ดลับที่นี่


0

หลังจากการทดสอบหลายครั้งฉันได้ตรวจสอบแล้วว่าคำถามเดิมนั้นถูกต้องแล้ว ไม่มีการตั้งค่าบางอย่าง:

  • container_rowต้องมีposition: relative;
  • เด็ก (... ) ต้องมี position: absolute; left:0;
  • เพื่อให้แน่ใจว่าเด็ก ๆ (... ) อยู่ในแนวเดียวกัน container_rowควรมีสไตล์เพิ่มเติม:
    • height:x; line-height:x; vertical-align:middle;
    • text-align:center; ยังสามารถช่วย
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.