Senaryo a se prèske toujou menm bagay la, ki se yon tab done andedan yon veso defilable. Chak ranje gen yon meni aksyon, yon ti dropdown ak kèk opsyon, tankou Edit, Duplicate, ak Efase. Ou bati l ', li sanble yo travay parfe nan izolasyon, ak Lè sa a, yon moun mete l' andedan div defilable sa a ak bagay sa yo tonbe apa. Mwen te wè ensèk egzak sa a nan twa baz kod diferan: veso a, chemine a, ak fondasyon an, tout diferan. Ensèk la, menm si, se totalman idantik. Dropdown la vin koupe nan kwen veso a. Oswa li parèt dèyè kontni ki ta dwe lojikman anba li. Oswa li travay byen jiskaske itilizatè a woule, ak Lè sa a, li dérive. Ou rive jwenn z-index: 9999. Pafwa li ede, men lòt fwa li pa fè absoliman anyen. Enkonsistans sa a se premye siy ke yon bagay pi pwofon k ap pase. Rezon ki fè li kontinye tounen se ke twa sistèm navigatè separe yo enplike, epi pifò devlopè yo konprann chak youn poukont li men pa janm panse sou sa k ap pase lè tout twa fè kolizyon: debòde, anpile kontèks, ak ki gen blòk.
Yon fwa ou konprann ki jan tout twa kominike, mòd echèk yo sispann santi yo o aza. An reyalite, yo vin previzib. Twa Bagay yo Aktyèlman Sa ki lakòz Ann gade nan chak nan atik sa yo an detay. Pwoblèm nan debòde Lè ou mete debòde: kache, debòde: woulo liv, oswa debòde: oto sou yon eleman, navigatè a pral koupe nenpòt bagay ki pwolonje pi lwen pase limit li yo, ki gen ladan desandan absoliman pozisyone. .scroll-container { debòde: oto; wotè: 300px; /* Sa a pral koupe deroule a, pwen */ }
.dropdown { pozisyon: absoli; /* Pa gen pwoblèm -- toujou koupe pa .scroll-container */ }
Sa te etone m premye fwa m te kouri sou li. Mwen ta sipoze pozisyon: absoli ta kite yon eleman chape anba koupe yon veso. Li pa fè sa. Nan pratik, sa vle di yon meni ki absoliman pozisyone ka koupe pa nenpòt zansèt ki gen yon valè debòde ki pa vizib, menm si zansèt sa a se pa blòk ki genyen meni a. Taye ak pwezante se sistèm separe. Yo jis rive fè kolizyon nan fason ki sanble konplètman o aza jiskaske ou konprann tou de.
Men yon egzanp React lè l sèvi avèk createPortal:
enpòte { createPortal } soti nan 'react-dom'; enpòte { useState, useEffect, useRef } soti nan 'react';
fonksyon Dropdown ({ anchorRef, isOpen, timoun }) { const [position, setPosition] = useState ({top: 0, left: 0});
useEffect(() => { if (isOpen && anchorRef.current) { const rect = anchorRef.current.getBoundingClientRect (); setPosition({ tèt: rect.bottom + window.scrollY, agoch: rect.left + window.scrollX, }); } }, [isOpen, anchorRef]);
si (!isOpen) retounen nil;
retounen kreye Portal(
Epi, nan kou, nou pa ka inyore aksè. Eleman fiks ki parèt sou kontni yo dwe toujou ka jwenn ak klavye. Si lòd konsantre a pa natirèlman deplase nan dropdown fiks la, w ap bezwen jere li lè l sèvi avèk kòd. Li la tou vo tcheke ke li pa chita sou lòt kontni entèaktif ki pa gen okenn fason yo ranvwaye li. Yon sèl mòde ou nan tès klavye. Pozisyon Anchor CSS: Ki kote mwen panse sa a se tit CSS Anchor Positioning se direksyon mwen pi enterese kounye a. Mwen pa t sèten ki kantite nan espèk la te aktyèlman ka itilize lè mwen te premye gade li. Li pèmèt ou deklare relasyon ki genyen ant yon dropdown ak deklanche li dirèkteman nan CSS, epi navigatè a okipe kowòdone yo. .deklanche { anchor-name: --my-trigger; }
.meni déroulant { pozisyon: absoli; pozisyon-lank: --mwen-deklanche; tèt: anchor (anba); gòch: anchor(left); pozisyon-eseye-fallbacks: baskile-blòk, baskile-inline; }
Pwopriyete pozisyon-eseye-fallbacks la se sa ki fè sa a vo itilize sou yon kalkil manyèl. Navigatè a eseye plasman altènatif anvan li abandone, kidonk yon dropdown nan pati anba a nan vi a otomatikman baskile anlè olye pou yo koupe. Sipò navigatè a solid nan navigatè ki baze sou Chromium epi li ap grandi nan Safari. Firefox bezwen yon polyfill. Pake @oddbird/css-anchor-positioning kouvri spesifikasyon debaz la. Mwen te frape ka rebò layout ak li ki te mande repli mwen pa t 'antisipe, kidonk trete li kòm yon amelyorasyon pwogresif oswa pè li ak yonJavaScript repli pou Firefox. Nan ti bout tan, pwomèt men pa inivèsèl ankò. Teste nan navigatè sib ou yo. Ak osi lwen ke aksè se konsène, deklare yon relasyon vizyèl nan CSS pa di pye bwa aksè a anyen. aria-controls, aria-expanded, aria-haspopup — pati sa a toujou sou ou. Pafwa ranje a jis deplase eleman an Anvan yo rive jwenn yon pòtal oswa fè kalkil kowòdone, mwen toujou poze yon kesyon an premye: Èske dropdown sa a aktyèlman bezwen viv andedan veso woulo liv la? Si li pa fè sa, deplase maketing la nan yon anbalaj pi wo nivo elimine pwoblèm nan totalman, ki pa gen okenn JavaScript ak pa gen okenn kalkil kowòdone. Sa a pa toujou posib. Si bouton an ak dropdown yo encapsulé nan menm eleman, deplase youn san lòt la vle di repanse tout API a. Men, lè ou ka fè li, pa gen anyen pou debogaj. Pwoblèm nan jis pa egziste. Ki sa ki modèn CSS toujou pa rezoud CSS te vini yon fason lontan isit la, men gen toujou kote li kite ou desann. Pozisyon an: pwoblèm fiks ak transfòme yo toujou la. Li nan espèk a entansyonèlman, ki vle di pa gen okenn solisyon CSS egziste. Si w ap itilize yon bibliyotèk animasyon ki vlope Layout ou a nan yon eleman transfòme, w ap tounen nan bezwen portails oswa pozisyon jete lank. Pozisyon Anchor CSS pwomèt, men nouvo. Kòm mansyone pi bonè, Firefox toujou bezwen yon polyfill nan moman mwen ekri sa a. Mwen te frape ka rebò layout ak li ki te mande repli mwen pa t 'antisipe. Si w bezwen yon konpòtman ki konsistan atravè tout navigatè jodi a, w ap toujou jwenn JavaScript pou pati ki difisil yo. Anplis de sa mwen te aktyèlman chanje workflow mwen an se HTML Popover API a, ki disponib kounye a nan tout navigatè modèn yo. Eleman ki gen atribi popover rann nan kouch anlè navigatè a, pi wo a tout bagay, san okenn pozisyon JavaScript nesesè.
Manyen chape, ranvwaye-sou-klik-deyò, ak semantik aksè solid vini gratis pou bagay tankou konsèy sou zouti, widgets divilgasyon, ak superpositions senp. Se premye zouti mwen jwenn pou kounye a. Sa te di, li pa rezoud pwezante. Li rezoud kouch. Ou toujou bezwen pozisyon jete lank oswa JavaScript pou fè aliman yon popover ak deklanche li. Popover API a okipe stratifikasyon an. Anchor pwezante okipe plasman an. Itilize ansanm, yo kouvri pi fò nan sa ou ta deja jwenn pou yon bibliyotèk fè. Yon Gid Desizyon Pou Sitiyasyon Ou Apre yo fin pase tout bagay sa yo nan fason difisil, men ki jan mwen aktyèlman panse sou chwa a kounye a.
Sèvi ak yon pòtal.Mwen ta sèvi ak sa a lè deklanche a ap viv byen fon nan resipyan woulo liv enbrike. Mwen te itilize modèl sa a pou meni aksyon tab epi mwen te asosye li ak restorasyon konsantre ak chèk aksè. Li se opsyon ki pi serye, men bidjè tan pou fil elektrik siplemantè a. Sèvi ak pozisyon fiks.Sa a se pou lè w ap nan vaniy JavaScript oswa yon fondasyon ki lejè epi yo pa ka verifye okenn zansèt aplike transfòme oswa filtè. Li senp pou mete kanpe ak senp pou debogaj, osi lontan ke yon sèl kontrent kenbe. Sèvi ak CSS Anchor Positioning.Reach pou sa lè sipò navigatè ou a pèmèt li. Si sipò Firefox nesesè, asosye li ak @oddbird polyfill la. Sa a se kote platfòm la finalman tit epi li pral evantyèlman vin apwòch ou ale. Restriktire DOM la. Sèvi ak sa a lè achitekti a pèmèt li, epi ou vle zewo konpleksite ègzekutabl. Mwen kwè ke li posib opsyon ki pi underrated. Konbine modèl.Fè sa a lè ou vle pozisyon jete lank kòm apwòch prensipal ou a, asosye ak yon repli JavaScript pou navigatè ki pa sipòte. Oswa yon pòtal pou plasman DOM ki asosye ak getBoundingClientRect() pou presizyon kowòdone.
Konklizyon Mwen te konn trete ensèk sa a kòm yon pwoblèm yon sèl - yon bagay yo patch ak deplase sou. Men, yon fwa mwen te chita avèk li ase lontan pou m konprann tout twa sistèm ki enplike - koupe debòde, anpile kontèks, ak ki gen blòk - li sispann santi o aza. Mwen te kapab gade nan yon dropdown kase epi imedyatman trase ki zansèt ki te responsab. Chanjman sa a nan fason mwen li DOM la se te yon bagay ki reyèl. Pa gen yon sèl bon repons. Sa mwen te rive jwenn depann de sa mwen te kapab kontwole nan kodbaz la: pòtal lè pye bwa zansèt la te enprevizib; pozisyon fiks lè li te pwòp ak senp; deplase eleman nan lè pa gen anyen ki te kanpe m '; ak pozisyon lank kounye a,kote mwen kapab. Kèlkeswa sa ou fini chwazi, pa trete aksè kòm dènye etap la. Nan eksperyans mwen, se egzakteman lè li vin sote. Relasyon ARIA yo, jesyon konsantre, konpòtman klavye a - sa yo pa poli. Yo fè pati sa ki fè bagay la aktyèlman travay. Tcheke kòd sous konplè a nan repo GitHub mwen an. Pli lwen Lekti Sa yo se referans mwen te kontinye retounen nan pandan m ap travay nan sa a:
Kontèks la anpile (MDN) "CSS Anchor Pozisyon Gid", Juan Diego Rodriguez "Kòmanse ak Popover API a", Godstime Aburu Floating UI (floating-ui.com) CSS debòde (MDN)