દૃશ્ય લગભગ હંમેશા સમાન હોય છે, જે સ્ક્રોલ કરી શકાય તેવા કન્ટેનરની અંદર એક ડેટા ટેબલ છે. દરેક પંક્તિમાં એક એક્શન મેનૂ હોય છે, જેમાં સંપાદન, ડુપ્લિકેટ અને ડિલીટ જેવા કેટલાક વિકલ્પો સાથે એક નાનું ડ્રોપડાઉન હોય છે. તમે તેને બનાવો છો, તે એકલતામાં સંપૂર્ણ રીતે કામ કરે છે તેવું લાગે છે, અને પછી કોઈ તેને સ્ક્રોલ કરી શકાય તેવા ડિવની અંદર મૂકે છે અને વસ્તુઓ અલગ પડી જાય છે. મેં આ ચોક્કસ બગને ત્રણ અલગ-અલગ કોડબેસેસમાં જોયો છે: કન્ટેનર, સ્ટેક અને ફ્રેમવર્ક, બધું જ અલગ. ભૂલ, જોકે, તદ્દન સમાન છે. ડ્રોપડાઉન કન્ટેનરની ધાર પર ક્લિપ થઈ જાય છે. અથવા તે સામગ્રીની પાછળ દેખાય છે જે તાર્કિક રીતે તેની નીચે હોવી જોઈએ. અથવા જ્યાં સુધી વપરાશકર્તા સ્ક્રોલ ન કરે ત્યાં સુધી તે સારું કામ કરે છે અને પછી તે વહી જાય છે. તમે z-ઇન્ડેક્સ માટે પહોંચો છો: 9999. કેટલીકવાર તે મદદ કરે છે, પરંતુ અન્ય સમયે તે બિલકુલ કંઈ કરતું નથી. તે અસંગતતા એ પ્રથમ સંકેત છે કે કંઈક ઊંડું થઈ રહ્યું છે. તે પાછા આવવાનું ચાલુ રાખવાનું કારણ એ છે કે ત્રણ અલગ-અલગ બ્રાઉઝર સિસ્ટમો સામેલ છે, અને મોટાભાગના વિકાસકર્તાઓ દરેકને પોતાની રીતે સમજે છે પરંતુ જ્યારે ત્રણેય એકબીજા સાથે અથડાય છે ત્યારે શું થાય છે તે વિશે ક્યારેય વિચારતા નથી: ઓવરફ્લો, સ્ટેકીંગ સંદર્ભો અને બ્લોક્સ ધરાવે છે.
એકવાર તમે સમજો કે ત્રણેય કેવી રીતે ક્રિયાપ્રતિક્રિયા કરે છે, નિષ્ફળતા મોડ્સ રેન્ડમ લાગવાનું બંધ કરે છે. હકીકતમાં, તેઓ અનુમાનિત બની જાય છે. ત્રણ વસ્તુઓ ખરેખર આનું કારણ બને છે ચાલો તે દરેક વસ્તુને વિગતવાર જોઈએ. ઓવરફ્લો સમસ્યા જ્યારે તમે ઓવરફ્લો સેટ કરો છો: છુપાયેલ, ઓવરફ્લો: સ્ક્રોલ, અથવા ઓવરફ્લો: ઓટો ઓન એલિમેન્ટ, બ્રાઉઝર તેની સીમાની બહાર વિસ્તરેલી કોઈપણ વસ્તુને ક્લિપ કરશે, જેમાં એકદમ સ્થિત થયેલ વંશજોનો સમાવેશ થાય છે. .સ્ક્રોલ-કન્ટેનર { ઓવરફ્લો: ઓટો; ઊંચાઈ: 300px; /* આ ડ્રોપડાઉનને ક્લિપ કરશે, પૂર્ણવિરામ */ }
.ડ્રોપડાઉન { સ્થિતિ: સંપૂર્ણ; /* કોઈ વાંધો નથી -- હજુ પણ .scroll-container દ્વારા ક્લિપ કરેલ છે */ }
પહેલીવાર જ્યારે હું તેમાં દોડ્યો ત્યારે મને આશ્ચર્ય થયું. હું પોઝિશન ધારણ કરીશ: નિરપેક્ષ એક તત્વને કન્ટેનરની ક્લિપિંગમાંથી છટકી જવા દેશે. તે નથી. વ્યવહારમાં, તેનો અર્થ એ છે કે સંપૂર્ણ રીતે સ્થિત થયેલ મેનૂ કોઈપણ પૂર્વજ દ્વારા કાપી શકાય છે કે જેની પાસે અદ્રશ્ય ઓવરફ્લો મૂલ્ય છે, પછી ભલે તે પૂર્વજ મેનૂનો બ્લોક ધરાવતા ન હોય. ક્લિપિંગ અને પોઝિશનિંગ અલગ સિસ્ટમ્સ છે. જ્યાં સુધી તમે બંનેને સમજો નહીં ત્યાં સુધી તેઓ સંપૂર્ણપણે અવ્યવસ્થિત લાગે તે રીતે અથડાય છે.
CreatePortal નો ઉપયોગ કરીને અહીં પ્રતિક્રિયાનું ઉદાહરણ છે:
'react-dom' માંથી { createPortal } આયાત કરો; 'પ્રતિક્રિયા' માંથી { 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 એન્કર પોઝિશનિંગ એ દિશા છે જેમાં મને અત્યારે સૌથી વધુ રસ છે. જ્યારે મેં તેને પહેલીવાર જોયું ત્યારે મને ખાતરી નહોતી કે કેટલી સ્પેક ખરેખર ઉપયોગી હતી. તે તમને સીએસએસમાં ડ્રોપડાઉન અને તેના ટ્રિગર વચ્ચેના સંબંધની જાહેરાત કરવા દે છે અને બ્રાઉઝર કોઓર્ડિનેટ્સને હેન્ડલ કરે છે. .ટ્રિગર { એન્કર-નામ: --my-trigger; }
.ડ્રોપડાઉન-મેનુ { સ્થિતિ: સંપૂર્ણ; પોઝિશન-એન્કર: --my-ટ્રિગર; ટોચ: એન્કર (નીચે); ડાબે: એન્કર(ડાબે); પોઝિશન-ટ્રાય-ફોલબેક્સ: ફ્લિપ-બ્લોક, ફ્લિપ-ઇનલાઇન; }
પોઝિશન-ટ્રાય-ફોલબેક્સ પ્રોપર્ટી તે છે જે મેન્યુઅલ ગણતરી પર ઉપયોગ કરવા યોગ્ય બનાવે છે. બ્રાઉઝર હાર કરતાં પહેલાં વૈકલ્પિક પ્લેસમેન્ટનો પ્રયાસ કરે છે, તેથી વ્યૂપોર્ટના તળિયે ડ્રોપડાઉન કપાઈ જવાને બદલે આપમેળે ઉપરની તરફ ફ્લિપ થઈ જાય છે. બ્રાઉઝર સપોર્ટ ક્રોમિયમ-આધારિત બ્રાઉઝર્સમાં મજબૂત છે અને સફારીમાં વધી રહ્યો છે. ફાયરફોક્સને પોલીફિલની જરૂર છે. @oddbird/css-anchor-positioning પેકેજ મુખ્ય સ્પેકને આવરી લે છે. મેં તેની સાથે લેઆઉટ એજ કેસોને હિટ કર્યા છે જેમાં ફૉલબૅક્સની આવશ્યકતા છે જેની મને અપેક્ષા ન હતી, તેથી તેને પ્રગતિશીલ ઉન્નતીકરણ તરીકે ગણો અથવા તેની સાથે જોડી કરોFirefox માટે JavaScript ફોલબેક. ટૂંકમાં, આશાસ્પદ પરંતુ હજુ સુધી સાર્વત્રિક નથી. તમારા લક્ષ્ય બ્રાઉઝર્સમાં પરીક્ષણ કરો. અને જ્યાં સુધી ઍક્સેસિબિલિટીનો સવાલ છે, CSSમાં વિઝ્યુઅલ રિલેશનશિપ જાહેર કરવાથી એક્સેસિબિલિટી ટ્રીને કંઈપણ કહેવાતું નથી. aria-controls, aria-expanded, aria-haspopup — તે ભાગ હજુ પણ તમારા પર છે. કેટલીકવાર ફિક્સ ફક્ત તત્વને ખસેડે છે પોર્ટલ પર પહોંચતા પહેલા અથવા સંકલન ગણતરીઓ કરતા પહેલા, હું હંમેશા એક પ્રશ્ન પૂછું છું: શું આ ડ્રોપડાઉન ખરેખર સ્ક્રોલ કન્ટેનરની અંદર રહેવાની જરૂર છે? જો તે ન થાય, તો માર્કઅપને ઉચ્ચ-સ્તરના રેપર પર ખસેડવાથી સમસ્યા સંપૂર્ણપણે દૂર થઈ જાય છે, જેમાં JavaScript અને કોઈ સંકલન ગણતરીઓ નથી. આ હંમેશા શક્ય નથી. જો બટન અને ડ્રોપડાઉન એક જ ઘટકમાં સમાવિષ્ટ હોય, તો એકને બીજા વિના ખસેડવાનો અર્થ એ છે કે સમગ્ર API પર પુનર્વિચાર કરવો. પરંતુ જ્યારે તમે તે કરી શકો છો, ત્યારે ડિબગ કરવા માટે કંઈ નથી. સમસ્યા ફક્ત અસ્તિત્વમાં નથી. શું આધુનિક CSS હજી પણ હલ કરતું નથી CSS અહીં ઘણો લાંબો માર્ગ આવ્યો છે, પરંતુ હજુ પણ એવી જગ્યાઓ છે જે તમને નિરાશ કરે છે. સ્થિતિ: નિશ્ચિત અને પરિવર્તન સમસ્યાઓ હજુ પણ છે. તે ઈરાદાપૂર્વક સ્પેકમાં છે, જેનો અર્થ છે કે કોઈ CSS વર્કઅરાઉન્ડ અસ્તિત્વમાં નથી. જો તમે એનિમેશન લાઇબ્રેરીનો ઉપયોગ કરી રહ્યાં છો જે તમારા લેઆઉટને રૂપાંતરિત ઘટકમાં લપેટી લે છે, તો તમારે પોર્ટલ અથવા એન્કર પોઝિશનિંગની જરૂર છે. CSS એન્કર પોઝિશનિંગ આશાસ્પદ છે, પરંતુ નવું છે. અગાઉ સૂચવ્યા મુજબ, હું આ લખી રહ્યો છું તે સમયે ફાયરફોક્સને હજી પણ પોલીફિલની જરૂર છે. મેં તેની સાથે લેઆઉટ એજ કેસોને હિટ કર્યા છે જેમાં ફૉલબૅક્સની જરૂર છે જેની મને અપેક્ષા નહોતી. જો તમને આજે બધા બ્રાઉઝર્સમાં સુસંગત વર્તનની જરૂર હોય, તો તમે હજી પણ મુશ્કેલ ભાગો માટે JavaScript સુધી પહોંચી રહ્યાં છો. મેં ખરેખર મારા વર્કફ્લોને જે વધારા માટે બદલ્યો છે તે HTML પોપઓવર API છે, જે હવે તમામ આધુનિક બ્રાઉઝર્સમાં ઉપલબ્ધ છે. પોપઓવર એટ્રિબ્યુટ સાથેના તત્વો બ્રાઉઝરના ટોચના સ્તરમાં, દરેક વસ્તુની ઉપર, JavaScript સ્થિતિની જરૂર નથી.
એસ્કેપ હેન્ડલિંગ, ડિસમિસ-ઓન-ક્લિક-આઉટ અને સોલિડ એક્સેસિબિલિટી સિમેન્ટિક્સ ટૂલટિપ્સ, ડિસ્ક્લોઝર વિજેટ્સ અને સરળ ઓવરલે જેવી વસ્તુઓ માટે મફતમાં આવે છે. તે પ્રથમ સાધન છે જે હું હમણાં માટે પહોંચું છું. તેણે કહ્યું, તે સ્થિતિને હલ કરતું નથી. તે લેયરિંગને હલ કરે છે. પોપઓવરને તેના ટ્રિગર સાથે સંરેખિત કરવા માટે તમારે હજી પણ એન્કર પોઝિશનિંગ અથવા JavaScriptની જરૂર છે. Popover API લેયરિંગને હેન્ડલ કરે છે. એન્કર પોઝિશનિંગ પ્લેસમેન્ટનું સંચાલન કરે છે. એકસાથે ઉપયોગમાં લેવાતા, તેઓ લાઇબ્રેરી કરવા માટે તમે અગાઉ પહોંચતા હો તે મોટા ભાગને આવરી લે છે. તમારી પરિસ્થિતિ માટે નિર્ણય માર્ગદર્શિકા આ બધાને સખત રીતે પસાર કર્યા પછી, હવે હું ખરેખર પસંદગી વિશે કેવી રીતે વિચારું છું તે અહીં છે.
પોર્ટલનો ઉપયોગ કરો. જ્યારે ટ્રિગર નેસ્ટેડ સ્ક્રોલ કન્ટેનરમાં ઊંડે સુધી રહે છે ત્યારે હું આનો ઉપયોગ કરીશ. મેં ટેબલ એક્શન મેનુ માટે આ પેટર્નનો ઉપયોગ કર્યો અને તેને ફોકસ રિસ્ટોરેશન અને એક્સેસિબિલિટી ચેક્સ સાથે જોડી બનાવી. તે સૌથી વિશ્વસનીય વિકલ્પ છે, પરંતુ વધારાના વાયરિંગ માટે બજેટ સમય. ફિક્સ્ડ પોઝિશનિંગનો ઉપયોગ કરો. જ્યારે તમે વેનીલા JavaScript અથવા લાઇટવેઇટ ફ્રેમવર્કમાં હોવ અને કોઈ પૂર્વજ રૂપાંતર અથવા ફિલ્ટર્સ લાગુ કરતું નથી ત્યારે તે ચકાસી શકે છે. જ્યાં સુધી તે એક અવરોધ ધરાવે છે ત્યાં સુધી તે સેટ કરવા માટે સરળ અને ડીબગ કરવા માટે સરળ છે. CSS એન્કર પોઝિશનિંગનો ઉપયોગ કરો. જ્યારે તમારું બ્રાઉઝર સપોર્ટ તેને મંજૂરી આપે ત્યારે આ માટે પહોંચો. જો ફાયરફોક્સ સપોર્ટ જરૂરી હોય, તો તેને @oddbird પોલીફિલ સાથે જોડી દો. આ તે છે જ્યાં પ્લેટફોર્મ આખરે આગળ વધી રહ્યું છે અને આખરે તે તમારો જવાનો અભિગમ બની જશે. DOM ને પુનઃરચના કરો. જ્યારે આર્કિટેક્ચર તેને પરવાનગી આપે ત્યારે તેનો ઉપયોગ કરો અને તમે શૂન્ય રનટાઇમ જટિલતા ઇચ્છો છો. હું માનું છું કે તે સંભવતઃ સૌથી અન્ડરરેટેડ વિકલ્પ છે. પેટર્નને ભેગું કરો. જ્યારે તમે તમારા પ્રાથમિક અભિગમ તરીકે એન્કર પોઝિશનિંગ ઇચ્છતા હોવ ત્યારે આ કરો, અસમર્થિત બ્રાઉઝર્સ માટે JavaScript ફૉલબેક સાથે જોડી બનાવી. અથવા સંકલન ચોકસાઈ માટે getBoundingClientRect() સાથે જોડાયેલ DOM પ્લેસમેન્ટ માટેનું પોર્ટલ.
નિષ્કર્ષ હું આ બગને એક જ સમસ્યા તરીકે ગણતો હતો — પેચ કરવા અને આગળ વધવા માટે કંઈક. પરંતુ એકવાર હું તેની સાથે ત્રણેય પ્રણાલીઓને સમજવા માટે પૂરતો સમય બેઠો - ઓવરફ્લો ક્લિપિંગ, સ્ટેકીંગ સંદર્ભો અને બ્લોક્સ - તે રેન્ડમ લાગવાનું બંધ કરી દીધું. હું તૂટેલા ડ્રોપડાઉનને જોઈ શકું છું અને તરત જ શોધી શકું છું કે કયો પૂર્વજ જવાબદાર હતો. હું DOM કેવી રીતે વાંચું છું તે બદલાવ એ વાસ્તવિક ઉપાડ હતો. કોઈ એક સાચો જવાબ નથી. હું જે માટે પહોંચ્યો તે કોડબેઝમાં હું શું નિયંત્રિત કરી શકું તેના પર નિર્ભર છે: પોર્ટલ જ્યારે પૂર્વજ વૃક્ષ અણધારી હતું; જ્યારે તે સ્વચ્છ અને સરળ હોય ત્યારે નિશ્ચિત સ્થિતિ; જ્યારે કંઈ મને રોકતું ન હતું ત્યારે તત્વને ખસેડવું; અને એન્કર પોઝિશનિંગ હવે,જ્યાં હું કરી શકું છું. તમે જે પણ પસંદ કરો છો, સુલભતાને છેલ્લું પગલું ગણશો નહીં. મારા અનુભવમાં, જ્યારે તે છોડવામાં આવે છે ત્યારે તે બરાબર છે. ARIA સંબંધો, ફોકસ મેનેજમેન્ટ, કીબોર્ડ વર્તન — તે પોલિશ નથી. વસ્તુને વાસ્તવમાં શું કામ બનાવે છે તેનો તેઓ એક ભાગ છે. મારા GitHub રેપોમાં સંપૂર્ણ સ્રોત કોડ તપાસો. વધુ વાંચન આ તે સંદર્ભો છે જે હું આ દ્વારા કામ કરતી વખતે પાછો આવતો રહ્યો:
સ્ટેકીંગ સંદર્ભ (MDN) "CSS એન્કર પોઝિશનિંગ ગાઇડ", જુઆન ડિએગો રોડ્રિગ્ઝ "ધ પોપઓવર API સાથે પ્રારંભ કરવું", ગોડસ્ટાઈમ અબુરુ ફ્લોટિંગ UI (floating-ui.com) CSS ઓવરફ્લો (MDN)