ตำแหน่งของฉัน: Sticky Element ไม่เหนียวเมื่อใช้ flexbox


115

ฉันติดอยู่กับเรื่องนี้เล็กน้อยและคิดว่าฉันจะแชร์สิ่งนี้position: sticky+ flexbox gotcha:

เหนียว Div ของฉันทำงานได้ดีจนกระทั่งฉันเปลี่ยนมุมมองของฉันไปยังคอนเทนเนอร์กล่องดิ้นและทันใดนั้น div ก็ไม่เหนียวเมื่อถูกห่อด้วยแม่แบบ flexbox

.flexbox-wrapper {
  display: flex;
  height: 600px;
}
.regular {
  background-color: blue;
}
.sticky {
  position: -webkit-sticky;
  position: sticky;
  top: 0;
  background-color: red;
}
<div class="flexbox-wrapper">
  <div class="regular">
    This is the regular box
  </div>
  <div class="sticky">
    This is the sticky box
  </div>
</div>

JSFiddle แสดงปัญหา


พฤติกรรมนี้ยังคงมีอยู่ในทุกเบราว์เซอร์ที่รองรับposition: stickyหรือเพียงตัวเดียวหรือไม่?
TylerH

1
@TylerH ฉันเชื่อว่ามันเป็นเบราว์เซอร์ทั้งหมด มันทำงานเช่นนี้ทั้งใน Chrome และ Safari
BHOLT

ขอบคุณ. ฉันสามารถยืนยันได้ว่าปัญหาและแนวทางแก้ไขเกิดขึ้นใน Firefox ด้วย
TylerH

คำตอบ:


220

เนื่องจากองค์ประกอบกล่องดิ้นมีค่าเริ่มต้นองค์ประกอบstretchทั้งหมดจึงมีความสูงเท่ากันซึ่งไม่สามารถเลื่อนเทียบได้

การเพิ่มalign-self: flex-startองค์ประกอบ Sticky จะตั้งค่าความสูงเป็นอัตโนมัติซึ่งอนุญาตให้เลื่อนและแก้ไขได้

ขณะนี้ได้รับการสนับสนุนในเบราว์เซอร์หลัก ๆ ทั้งหมด แต่ Safari ยังคงอยู่หลัง-webkit-คำนำหน้าและเบราว์เซอร์อื่น ๆ ยกเว้น Firefox มีปัญหาบางอย่างเกี่ยวกับposition: stickyตาราง

.flexbox-wrapper {
  display: flex;
  overflow: auto;
  height: 200px;          /* Not necessary -- for example only */
}
.regular {
  background-color: blue; /* Not necessary -- for example only */
  height: 600px;          /* Not necessary -- for example only */
}
.sticky {
  position: -webkit-sticky; /* for Safari */
  position: sticky;
  top: 0;
  align-self: flex-start; /* <-- this is the fix */
  background-color: red;  /* Not necessary -- for example only */
}
<div class="flexbox-wrapper">
  <div class="regular">
    This is the regular box
  </div>
  <div class="sticky">
    This is the sticky box
  </div>
</div>

JSFiddle แสดงวิธีแก้ปัญหา


26
สิ่งนี้ใช้ได้เฉพาะเมื่อเลื่อนภายในองค์ประกอบ Flex ที่มี - เมื่อเลื่อนทั้งหน้าต่างจะไม่ติด (อย่างน้อยใน Firefox) - ดังนั้นสำหรับผู้ที่มีพฤติกรรมที่ขัดแย้งกันมีแนวโน้มว่าคุณจะพบกับความคาดหวังที่ขัดแย้งกัน (เช่น i เป็น)
aequalsb

@aequalsb คุณรู้วิธีทำให้ติดเมื่อเลื่อนทั้งหน้าหรือไม่?
Douglas Gaskell

@ ดักลาสเป็นคำถามที่ทำให้เข้าใจผิดเพราะมันแสดงให้เห็นว่าปัญหาเกิดขึ้นflexboxแต่ปัญหานั้นเกี่ยวข้องกับการมีstickyองค์ประกอบมากกว่า ดูซอนี้: jsfiddle.net/9y87zL5cที่กล่องสีแดงที่สองทำงานตามที่คาดไว้ แต่กล่องสีแดง FIRST ไม่ติด - ดังนั้น ... สิ่งนี้ไม่เกี่ยวข้องกับ flexbox (ดังนั้นจึงขัดแย้งกับความคาดหวัง) ... นอกจากนี้ ... เพิ่ม jabberwocky จำนวนมากเพื่อดูผลลัพธ์ในลักษณะที่แม่นยำยิ่งขึ้น
aequalsb

30

ในกรณีของฉันหนึ่งในคอนเทนเนอร์ระดับบนสุดได้overflow-x: hidden;นำไปใช้กับคอนเทนเนอร์ซึ่งจะทำลายposition: stickyฟังก์ชันการทำงาน คุณจะต้องลบกฎนั้นออก

องค์ประกอบหลักไม่ควรมีการใช้กฎ CSS ด้านบน เงื่อนไขนี้ใช้กับพ่อแม่ทุกคนจนถึงองค์ประกอบ "ร่างกาย" (แต่ไม่รวมถึง)


คุณไม่สามารถมีoverflow-x:hiddenในองค์ประกอบ html
Samuel Liew

ขอบคุณมาก. ฉันต่อสู้กับตำแหน่งที่เหนียวอยู่เสมอและฉันไม่รู้เกี่ยวกับเงื่อนไขนี้จนกว่าจะอ่านคำตอบของคุณ :)
Raphael Aleixo

1
@SamuelLiew ใช่คุณสามารถมีoverflow-x: hidden;ในองค์ประกอบ HTML
TheoPlatica

@RaphaelAleixo ฉันดีใจที่ช่วยได้ :)
TheoPlatica

นี่คือสิ่งที่ปิดกั้นฉันจากการทำงานอย่างถูกต้อง ขอบคุณมาก!
MoOx

7

คุณยังสามารถลองเพิ่ม div ลูกลงในรายการ flex ที่มีเนื้อหาอยู่ข้างในแล้วกำหนดposition: sticky; top: 0;ให้

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


เห็นด้วยอย่างยิ่งนี่เป็นตัวเลือกที่ง่ายและน่าเชื่อถือที่สุดที่ฉันสามารถหาได้ ด้วยวิธีนี้คุณจะสามารถควบคุมเวลาที่จะหยุดการเกาะติดได้โดยการควบคุมความสูงของภาชนะ
Ibrahim ben Salah

0

ฉันทำตารางเฟล็กบ็อกซ์ชั่วคราวและมีปัญหานี้ ในการแก้ปัญหานี้ฉันเพียงแค่วางแถวส่วนหัวแบบเหนียวไว้ด้านนอกของ flexbox ก่อนหน้านั้น


0

สำหรับสถานการณ์ของฉันวิธีแก้ปัญหาalign-self: flex-start(หรือjustify-self: flex-start) ไม่ทำงาน ฉันจำเป็นต้องเก็บไว้overflow-x: hiddenเช่นกันเนื่องจากตู้คอนเทนเนอร์บางส่วนปัดในแนวนอน

ทางออกของฉันต้องซ้อนกันdisplay: flexกับoverflow-y: autoที่จะได้รับพฤติกรรมที่ต้องการ:

  • ส่วนหัวสามารถปรับความสูงแบบไดนามิกซึ่งป้องกันไม่ให้เล่นด้วยposition: absoluteหรือposition: fixed
  • เนื้อหาจะเลื่อนในแนวตั้ง จำกัด ตามแนวนอนไปที่ความกว้างของมุมมอง
  • องค์ประกอบเหนียวสามารถอยู่ที่ใดก็ได้ในแนวตั้งโดยติดที่ด้านล่างของส่วนหัว
  • องค์ประกอบอื่น ๆ สามารถเลื่อนในแนวนอนได้
    • ดูเหมือนเครื่องมือ SO snippet ไม่สามารถแสดงผลwidthในองค์ประกอบลูกได้อย่างถูกต้องเพื่อสาธิตสไลด์แนวนอนหรืออาจมีการตั้งค่าอื่น ๆ ในเค้าโครงจริงของฉันที่ทำให้ใช้งานได้
    • โปรดทราบว่าองค์ประกอบของ wrapper ที่ไม่จำเป็นต้องทำอะไรอีกเพื่อให้overflow-x: autoทำงานได้อย่างถูกต้องในองค์ประกอบภายใต้พาเรนต์overflow-x: hidden

body {
  height: 100vh;
  width: 100vw;
  display: flex;
  flex-direction: column;
}

body>header {
  background-color: red;
  color: white;
  padding: 1em;
}

.content {
  overflow-x: hidden;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
}

article {
  position: relative;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
}

.horizontal_slide {
  display: flex;
  overflow-x: auto;
  background-color: lightblue;
  padding: .5em;
}

.horizontal_slide>* {
  width: 1000px;
}

.toolbar {
  position: sticky;
  top: 0;
  z-index: 10;
  background-color: lightgray;
  padding: .5em;
  display: flex;
}
<header>Fancy header with height adjusting to variable content</header>
<div class="content">
  <article class="card">
    <h1>One of several cards that flips visibility</h1>
    <div class="overflow_x_wrapper">
      <div class="horizontal_slide">
        <div>Reason why `overflow-x: hidden` on the parent is required
        </div>
        <div>Reason why `overflow-x: hidden` on the parent is required
        </div>
        <div>Reason why `overflow-x: hidden` on the parent is required
        </div>
      </div>
      <div class="toolbar">Sticky toolbar part-way down the content</div>
      <p>Rest of vertically scrollable container with variable number of child containers and other elements</p>
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure
        dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
  </article>
  </div>

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