परिस्थिती जवळजवळ नेहमीच सारखीच असते, जी स्क्रोल करण्यायोग्य कंटेनरमधील डेटा टेबल असते. प्रत्येक पंक्तीमध्ये एक क्रिया मेनू असतो, संपादन, डुप्लिकेट आणि हटवा यासारख्या काही पर्यायांसह एक छोटा ड्रॉपडाउन असतो. तुम्ही ते तयार करता, ते एकाकीपणात उत्तम प्रकारे काम करते असे दिसते आणि नंतर कोणीतरी ते त्या स्क्रोल करण्यायोग्य div मध्ये ठेवते आणि गोष्टी बाजूला पडतात. मी हा अचूक बग तीन वेगवेगळ्या कोडबेसमध्ये पाहिला आहे: कंटेनर, स्टॅक आणि फ्रेमवर्क, सर्व भिन्न. बग, तथापि, पूर्णपणे एकसारखे आहे. ड्रॉपडाउन कंटेनरच्या काठावर कापला जातो. किंवा ती सामग्रीच्या मागे दिसते जी तार्किकदृष्ट्या त्याच्या खाली असावी. किंवा वापरकर्ता स्क्रोल करेपर्यंत ते चांगले कार्य करते आणि नंतर ते वाहून जाते. तुम्ही z-इंडेक्स: 9999 पर्यंत पोहोचता. कधीकधी ते मदत करते, परंतु इतर वेळी ते काहीच करत नाही. ती विसंगती ही पहिली सूचना आहे की काहीतरी खोलवर घडत आहे. ते परत येत राहण्याचे कारण म्हणजे तीन स्वतंत्र ब्राउझर सिस्टीम गुंतलेले आहेत आणि बहुतेक डेव्हलपर प्रत्येकाला स्वतःहून समजून घेतात परंतु तिन्ही टक्कर झाल्यावर काय होते याचा कधीही विचार करत नाहीत: ओव्हरफ्लो, स्टॅकिंग कॉन्टेक्स्ट आणि ब्लॉक्स असलेले.
तिन्ही कसे परस्पर संवाद साधतात हे समजल्यावर, अपयश मोड यादृच्छिक वाटणे थांबवतात. किंबहुना ते प्रेडिक्टेबल बनतात. यास कारणीभूत असलेल्या तीन गोष्टी चला त्या प्रत्येक आयटमचा तपशीलवार विचार करूया. ओव्हरफ्लो समस्या जेव्हा तुम्ही ओव्हरफ्लो: लपविलेले, ओव्हरफ्लो: स्क्रोल किंवा ओव्हरफ्लो: एखाद्या घटकावर ऑटो सेट करता, तेव्हा ब्राउझर पूर्णपणे स्थानबद्ध वंशजांसह, त्याच्या मर्यादेच्या पलीकडे विस्तारलेली कोणतीही गोष्ट क्लिप करेल. .स्क्रोल-कंटेनर { ओव्हरफ्लो: ऑटो; उंची: 300px; /* हे ड्रॉपडाउन क्लिप करेल, पूर्णविराम */ }
.ड्रॉपडाउन { स्थिती: निरपेक्ष; /* काही फरक पडत नाही -- तरीही .scroll-container */ }
मी प्रथमच त्यात घुसलो तेव्हा मला आश्चर्य वाटले. मी स्थान गृहीत धरले आहे: absolute एखाद्या घटकाला कंटेनरच्या क्लिपिंगमधून बाहेर पडू देईल. ते होत नाही. प्रॅक्टिसमध्ये, याचा अर्थ असा आहे की तो पूर्वज मेनूचा ब्लॉक असलेला नसला तरीही, दृश्यमान ओव्हरफ्लो मूल्य असलेल्या कोणत्याही पूर्वजांकडून पूर्णपणे स्थानबद्ध मेनू कापला जाऊ शकतो. क्लिपिंग आणि पोझिशनिंग स्वतंत्र प्रणाली आहेत. जोपर्यंत तुम्ही दोन्ही समजून घेत नाही तोपर्यंत ते पूर्णपणे यादृच्छिक दिसणाऱ्या मार्गांनी टक्कर देतात.
येथे CreatePortal वापरून प्रतिक्रिया उदाहरण आहे:
'react-dom' वरून { createPortal } आयात करा; 'react' वरून { useState, useEffect, useRef } आयात करा;
फंक्शन ड्रॉपडाउन({ anchorRef, isOpen, Children }) { const [position, setPosition] = useState({ top: 0, left: 0 });
useEffect(() => { जर (isOpen && anchorRef.current) { const rect = anchorRef.current.getBoundingClientRect(); सेटपोझिशन({ शीर्ष: rect.bottom + window.scrollY, डावीकडे: rect.left + window.scrollX, }); } }, [isOpen, anchorRef]);
जर (!isOpen) रिटर्न शून्य;
परत तयार करा पोर्टल(
आणि, अर्थातच, आम्ही प्रवेशयोग्यतेकडे दुर्लक्ष करू शकत नाही. सामग्रीवर दिसणारे निश्चित घटक अद्याप कीबोर्ड-पोहोचण्यायोग्य असले पाहिजेत. फोकस ऑर्डर नैसर्गिकरित्या निश्चित ड्रॉपडाउनमध्ये जात नसल्यास, तुम्हाला तो कोड वापरून व्यवस्थापित करण्याची आवश्यकता असेल. हे देखील तपासण्यासारखे आहे की ते डिसमिस करण्याचा कोणताही मार्ग नसताना इतर परस्परसंवादी सामग्रीवर बसत नाही. कीबोर्ड चाचणीमध्ये तो तुम्हाला चावतो. CSS अँकर पोझिशनिंग: जिथे मला वाटते की हे हेडिंग आहे CSS अँकर पोझिशनिंग ही दिशा मला सध्या सर्वात जास्त स्वारस्य आहे. जेव्हा मी पहिल्यांदा ते पाहिले तेव्हा मला खात्री नव्हती की किती विशिष्टता वापरण्यायोग्य आहे. हे तुम्हाला ड्रॉपडाउन आणि त्याचे ट्रिगर यांच्यातील संबंध थेट CSS मध्ये घोषित करू देते आणि ब्राउझर निर्देशांक हाताळतो. .trigger { अँकर-नाव: --माय-ट्रिगर; }
ड्रॉपडाउन मेनू { स्थिती: निरपेक्ष; स्थिती-अँकर: --माय-ट्रिगर; शीर्ष: अँकर (तळाशी); डावीकडे: अँकर (डावीकडे); पोझिशन-ट्राय-फॉलबॅक: फ्लिप-ब्लॉक, फ्लिप-इनलाइन; }
पोझिशन-ट्राय-फॉलबॅक गुणधर्म हे मॅन्युअल गणनेवर वापरण्यास योग्य बनवते. ब्राउझर हार मानण्यापूर्वी पर्यायी प्लेसमेंटचा प्रयत्न करतो, त्यामुळे व्ह्यूपोर्टच्या तळाशी एक ड्रॉपडाउन कट ऑफ होण्याऐवजी आपोआप वरच्या दिशेने फ्लिप होतो. क्रोमियम-आधारित ब्राउझरमध्ये ब्राउझर समर्थन मजबूत आहे आणि सफारीमध्ये वाढत आहे. फायरफॉक्सला पॉलीफिल आवश्यक आहे. @oddbird/css-anchor-positioning पॅकेज मुख्य तपशील कव्हर करते. मला अपेक्षित नसलेल्या फॉलबॅकची आवश्यकता असलेल्या लेआउट एज केसेस मी मारल्या आहेत, म्हणून यास प्रगतीशील सुधारणा म्हणून समजा किंवा त्यास एकFirefox साठी JavaScript फॉलबॅक. थोडक्यात, आशादायक परंतु अद्याप सार्वत्रिक नाही. आपल्या लक्ष्यित ब्राउझरमध्ये चाचणी करा. आणि जोपर्यंत प्रवेशयोग्यतेचा संबंध आहे, CSS मध्ये व्हिज्युअल संबंध घोषित करणे प्रवेशयोग्यतेच्या झाडाला काहीही सांगत नाही. aria-controls, aria-expanded, aria-haspopup — तो भाग अजूनही तुमच्यावर आहे. कधीकधी फिक्स फक्त घटक हलवत असतो पोर्टलवर पोहोचण्यापूर्वी किंवा समन्वय गणना करण्यापूर्वी, मी नेहमी प्रथम एक प्रश्न विचारतो: हे ड्रॉपडाउन खरोखर स्क्रोल कंटेनरमध्ये असणे आवश्यक आहे का? तसे न झाल्यास, मार्कअपला उच्च-स्तरीय रॅपरवर हलवल्याने समस्या पूर्णपणे काढून टाकली जाते, कोणत्याही JavaScriptशिवाय आणि कोणत्याही समन्वय गणनाशिवाय. हे नेहमीच शक्य नसते. जर बटण आणि ड्रॉपडाउन एकाच घटकामध्ये एन्कॅप्स्युलेट केले असतील, तर एकाला दुसऱ्याशिवाय हलवणे म्हणजे संपूर्ण API चा पुनर्विचार करणे. परंतु जेव्हा तुम्ही ते करू शकता, तेव्हा डीबग करण्यासाठी काहीही नाही. समस्या फक्त अस्तित्वात नाही. काय आधुनिक CSS अजूनही सोडवत नाही CSS येथे खूप पुढे आले आहे, परंतु अजूनही अशी ठिकाणे आहेत जी तुम्हाला निराश करू देतात. स्थिती: निश्चित आणि रूपांतर समस्या अजूनही आहेत. हे जाणूनबुजून स्पेसमध्ये आहे, याचा अर्थ CSS वर्कअराउंड अस्तित्वात नाही. तुमचा लेआउट बदललेल्या घटकामध्ये गुंडाळणारी ॲनिमेशन लायब्ररी तुम्ही वापरत असल्यास, तुम्हाला पोर्टल किंवा अँकर पोझिशनिंगची आवश्यकता आहे. CSS अँकर पोझिशनिंग आशादायक आहे, परंतु नवीन आहे. आधी सांगितल्याप्रमाणे, मी हे लिहित असताना फायरफॉक्सला अजूनही पॉलीफिलची आवश्यकता आहे. मला अपेक्षित नसलेल्या फॉलबॅकची आवश्यकता असलेल्या लेआउट एज केसेस मी मारल्या आहेत. आज तुम्हाला सर्व ब्राउझरमध्ये सातत्यपूर्ण वागण्याची आवश्यकता असल्यास, तुम्ही अजूनही अवघड भागांसाठी JavaScript पर्यंत पोहोचत आहात. मी माझ्या वर्कफ्लोसाठी प्रत्यक्षात बदल केला आहे तो HTML Popover API, आता सर्व आधुनिक ब्राउझरमध्ये उपलब्ध आहे. पॉपओव्हर विशेषता असलेले घटक कोणत्याही JavaScript पोझिशनिंगची आवश्यकता नसताना, ब्राउझरच्या वरच्या लेयरमध्ये रेंडर होतात.
एस्केप हँडलिंग, डिसमिस-ऑन-क्लिक-आउट, आणि ठोस प्रवेशयोग्यता शब्दार्थ टूलटिप, प्रकटीकरण विजेट्स आणि साधे आच्छादन यासारख्या गोष्टींसाठी विनामूल्य येतात. मी आत्तापर्यंत पोहोचलेले हे पहिले साधन आहे. ते म्हणाले, ते पोझिशनिंग सोडवत नाही. हे लेयरिंग सोडवते. पॉपओव्हरला त्याच्या ट्रिगरवर संरेखित करण्यासाठी तुम्हाला अद्याप अँकर पोझिशनिंग किंवा JavaScript आवश्यक आहे. Popover API लेयरिंग हाताळते. अँकर पोझिशनिंग प्लेसमेंट हाताळते. एकत्र वापरलेले, लायब्ररीसाठी तुम्ही पूर्वी पोहोचलेल्या बहुतेक गोष्टी ते कव्हर करतात. तुमच्या परिस्थितीसाठी निर्णय मार्गदर्शक हे सर्व कठीण मार्गाने गेल्यानंतर, मी आता निवडीबद्दल खरोखर कसा विचार करतो ते येथे आहे.
पोर्टल वापरा. जेव्हा ट्रिगर नेस्टेड स्क्रोल कंटेनरमध्ये खोलवर राहतो तेव्हा मी हे वापरेन. मी हा पॅटर्न टेबल ॲक्शन मेनूसाठी वापरला आणि फोकस रिस्टोरेशन आणि ऍक्सेसिबिलिटी चेकसह जोडले. हा सर्वात विश्वासार्ह पर्याय आहे, परंतु अतिरिक्त वायरिंगसाठी बजेट वेळ आहे. निश्चित पोझिशनिंग वापरा. तुम्ही व्हॅनिला JavaScript किंवा लाइटवेट फ्रेमवर्कमध्ये असाल आणि कोणताही पूर्वज ट्रान्सफॉर्म किंवा फिल्टर लागू करत नाही याची पडताळणी करू शकता तेव्हा हे आहे. सेट करणे सोपे आहे आणि डीबग करणे सोपे आहे, जोपर्यंत ती एक मर्यादा आहे. CSS अँकर पोझिशनिंग वापरा. जेव्हा तुमचा ब्राउझर सपोर्ट परवानगी देईल तेव्हा यासाठी पोहोचा. फायरफॉक्स समर्थन आवश्यक असल्यास, ते @oddbird पॉलीफिलसह जोडा. हेच प्लॅटफॉर्म शेवटी पुढे जात आहे आणि शेवटी तुमचा जाण्याचा दृष्टीकोन बनेल. DOM ची पुनर्रचना करा. आर्किटेक्चरने परवानगी दिल्यावर याचा वापर करा आणि तुम्हाला शून्य रनटाइम क्लिष्टता हवी आहे. माझा विश्वास आहे की हा बहुधा सर्वात कमी दर्जाचा पर्याय आहे. नमुने एकत्र करा. तुम्हाला तुमचा प्राथमिक दृष्टिकोन म्हणून अँकर पोझिशनिंग हवी असेल तेव्हा हे करा, असमर्थित ब्राउझरसाठी JavaScript फॉलबॅकसह जोडलेले. किंवा समन्वय अचूकतेसाठी getBoundingClientRect() सह जोडलेले DOM प्लेसमेंटसाठी पोर्टल.
निष्कर्ष मी या बगला एक-एक समस्या मानत असे — पॅच करण्यासाठी आणि पुढे जाण्यासाठी काहीतरी. पण एकदा मी त्यात गुंतलेल्या तिन्ही सिस्टीम - ओव्हरफ्लो क्लिपिंग, स्टॅकिंग कॉन्टेक्स्ट आणि ब्लॉक्स असलेले - समजून घेण्यासाठी पुरेसा वेळ बसलो तेव्हा ते यादृच्छिक वाटणे बंद झाले. मी तुटलेल्या ड्रॉपडाऊनकडे पाहू शकलो आणि कोणता पूर्वज जबाबदार होता ते लगेच शोधू शकलो. मी DOM कसे वाचले यातील बदल हा खरा मार्ग होता. कोणतेही एकच योग्य उत्तर नाही. मी ज्यासाठी पोहोचलो ते कोडबेसमध्ये मी काय नियंत्रित करू शकतो यावर अवलंबून आहे: जेव्हा पूर्वज वृक्ष अप्रत्याशित होता तेव्हा पोर्टल; जेव्हा ते स्वच्छ आणि सोपे होते तेव्हा निश्चित स्थिती; जेव्हा काहीही मला थांबवत नव्हते तेव्हा घटक हलवणे; आणि आता अँकर पोझिशनिंग,जिथे मी करू शकतो. तुम्ही जे काही निवडता ते शेवटी, प्रवेशयोग्यता ही शेवटची पायरी मानू नका. माझ्या अनुभवानुसार, ते वगळले जाते तेव्हाच. ARIA संबंध, फोकस व्यवस्थापन, कीबोर्ड वर्तन — ते पॉलिश नाहीत. गोष्ट प्रत्यक्षात कार्य करते त्याचा ते भाग आहेत. माझ्या GitHub रेपोमध्ये संपूर्ण स्त्रोत कोड पहा. पुढील वाचन याद्वारे काम करताना मी परत येत राहिलेले हे संदर्भ आहेत:
स्टॅकिंग कॉन्टेक्स्ट (MDN) "CSS अँकर पोझिशनिंग मार्गदर्शक", जुआन दिएगो रॉड्रिग्ज "पॉपओव्हर API सह प्रारंभ करणे", Godstime Aburu फ्लोटिंग UI (floating-ui.com) CSS ओव्हरफ्लो (MDN)