Scenario je gotovo uvijek isti, a to je tabela podataka unutar kontejnera koji se može pomicati. Svaki red ima meni radnji, mali padajući meni sa nekim opcijama, kao što su Edit, Duplicate i Delete. Sagradite ga, čini se da savršeno radi u izolaciji, a onda ga neko stavi u taj div koji se može pomicati i stvari se raspadaju. Vidio sam ovu tačnu grešku u tri različite baze koda: kontejneru, steku i okviru, sve različite. Greška je, međutim, potpuno identična. Padajući meni se iseče na ivici kontejnera. Ili se pojavljuje iza sadržaja koji bi logično trebao biti ispod njega. Ili radi dobro dok korisnik ne skroluje, a onda se pomera. Posegnete za z-indeksom: 9999. Ponekad pomaže, ali drugi put ne radi apsolutno ništa. Ta nedosljednost je prvi trag da se dešava nešto dublje. Razlog zašto se stalno vraća je taj što su uključena tri odvojena sistema pretraživača, i većina programera razume svaki za sebe, ali nikada ne razmišlja o tome šta se dešava kada se sva tri sudare: prelivanje, slaganje konteksta i blokovi koji sadrže.

Jednom kada shvatite kako su sva tri u interakciji, načini kvara prestaju se osjećati nasumično. U stvari, postaju predvidljivi. Tri stvari koje to zapravo uzrokuju Pogledajmo svaki od tih stavki detaljno. Problem prelivanja Kada postavite overflow: hidden, overflow: scroll ili overflow: auto na element, pretraživač će isjeći sve što se proteže izvan njegovih granica, uključujući apsolutno pozicionirane potomke. .scroll-container { overflow: auto; visina: 300px; /* Ovo će isjeći padajući meni, tačka */ }

.padajući { pozicija: apsolutna; /* Nije važno -- još uvijek je isječen .scroll-container */ }

To me je iznenadilo kada sam prvi put naleteo na to. Pretpostavio sam poziciju: apsolutno bi omogućilo elementu da izbjegne isječak kontejnera. nije. U praksi, to znači da apsolutno pozicionirani meni može biti odsječen od strane bilo kojeg pretka koji ima nevidljivu vrijednost prelivanja, čak i ako taj predak nije blok koji sadrži meni. Klipljenje i pozicioniranje su odvojeni sistemi. Slučajno se sudare na načine koji izgledaju potpuno nasumično dok ne shvatite oboje.

Evo primjera Reacta koristeći createPortal:

import { createPortal } iz 'react-dom'; import { useState, useEffect, useRef } iz 'react';

function Dropdown({ anchorRef, isOpen, djeca }) { const [pozicija, setPosition] = useState({ vrh: 0, lijevo: 0 });

useEffect(() => { if (isOpen && anchorRef.current) { const rect = anchorRef.current.getBoundingClientRect(); setPosition({ gore: rect.bottom + window.scrollY, lijevo: rect.left + window.scrollX, }); } }, [isOpen, anchorRef]);

if (!isOpen) vrati null;

vrati createPortal(

, dokument.tijelo ); }

I, naravno, ne možemo zanemariti pristupačnost. Fiksni elementi koji se pojavljuju iznad sadržaja moraju i dalje biti dostupni tipkovnici. Ako se redoslijed fokusa prirodno ne pomiče u fiksni padajući izbornik, morat ćete njime upravljati pomoću koda. Također je vrijedno provjeriti da ne stoji preko drugog interaktivnog sadržaja bez načina da ga odbacite. Taj te ugrize u testiranju tastature. Pozicioniranje CSS sidra: gdje mislim da ovo vodi CSS Anchor Positioning je pravac koji me trenutno najviše zanima. Nisam bio siguran koliko je specifikacija zapravo upotrebljiva kada sam je prvi put pogledala. Omogućava vam da deklarirate odnos između padajućeg menija i njegovog okidača direktno u CSS-u, a pretraživač upravlja koordinatama. .trigger { sidro-ime: --moj-okidač; }

.dropdown-menu { pozicija: apsolutna; position-anchor: --my-trigger; vrh: sidro (dole); lijevo: sidro (lijevo); position-try-fallbacks: flip-block, flip-inline; }

Svojstvo position-try-fallbacks je ono što ovo čini vrijednim korištenja u odnosu na ručno izračunavanje. Pregledač pokušava alternativne položaje prije nego što odustane, tako da se padajući meni na dnu okvira za prikaz automatski okreće prema gore umjesto da bude odrezan. Podrška pretraživača je solidna u pretraživačima zasnovanim na Chromiumu i raste u Safariju. Firefoxu je potreban polifil. Paket @oddbird/css-anchor-positioning pokriva osnovne specifikacije. S njim sam pogodio rubne slučajeve rasporeda koji su zahtijevali zamjene koje nisam očekivao, pa ga tretirajte kao progresivno poboljšanje ili ga uparite sZamjena za JavaScript za Firefox. Ukratko, obećavajuće, ali još uvijek nisu univerzalne. Testirajte u vašim ciljanim pretraživačima. A što se pristupačnosti tiče, deklarisanje vizuelnog odnosa u CSS-u ništa ne govori stablu pristupačnosti. aria-controls, aria-expanded, aria-haspopup — taj dio je još uvijek na vama. Ponekad je popravka samo pomicanje elementa Prije nego što posegnem za portalom ili izvršim izračunavanje koordinata, uvijek prvo postavim jedno pitanje: Da li ovaj padajući meni zaista treba da živi unutar kontejnera za pomicanje? Ako se to ne dogodi, premještanje oznake na omotač višeg nivoa u potpunosti eliminira problem, bez JavaScripta i izračunavanja koordinata. Ovo nije uvijek moguće. Ako su dugme i padajući meni inkapsulirani u istoj komponenti, pomeranje jednog bez drugog znači preispitivanje celog API-ja. Ali kada to možete učiniti, nema šta za otklanjanje grešaka. Problem jednostavno ne postoji. Ono što moderni CSS još uvijek ne rješava CSS je ovdje prešao dug put, ali još uvijek ima mjesta na kojima vas iznevjerava. Položaj: popravljeni problemi i problemi transformacije su i dalje prisutni. Namjerno je u specifikaciji, što znači da ne postoji CSS zaobilazno rješenje. Ako koristite biblioteku animacije koja umotava vaš izgled u transformirani element, vratili ste se potrebnim portalima ili pozicioniranju sidra. CSS Anchor Pozicioniranje je obećavajuće, ali novo. Kao što je ranije spomenuto, Firefoxu je još uvijek potreban polifil u vrijeme kada ovo pišem. S njim sam pogodio rubne slučajeve rasporeda koji su zahtijevali zamjene koje nisam očekivao. Ako vam je potrebno dosljedno ponašanje u svim pretraživačima danas, još uvijek posežete za JavaScriptom za lukave dijelove. Dodatak za koji sam zapravo promijenio svoj radni tok je HTML Popover API, koji je sada dostupan u svim modernim pretraživačima. Elementi sa atributom popover se prikazuju u gornjem sloju pretraživača, iznad svega, bez potrebe za JavaScript pozicioniranjem.

Izbjegavanje rukovanja, odbacivanje na klik izvana i solidna semantika pristupačnosti su besplatni za stvari kao što su opisi alata, widgeti za otkrivanje i jednostavna preklapanja. To je prvi alat do kojeg sada posegnem. Međutim, to ne rješava pozicioniranje. Rješava slojevitost. I dalje vam je potrebno pozicioniranje sidra ili JavaScript da biste poravnali skočni prozor sa njegovim okidačem. Popover API upravlja slojevitošću. Pozicioniranje sidra upravlja postavljanjem. Kada se koriste zajedno, pokrivaju većinu onoga što ste prethodno posegnuli za bibliotekom. Vodič za donošenje odluka za vašu situaciju Nakon što sam sve ovo prošao na teži način, evo kako sada zapravo razmišljam o izboru.

Koristite portal. Koristio bih ovo kada okidač živi duboko u ugniježđenim kontejnerima za pomicanje. Koristio sam ovaj obrazac za menije radnji u tabeli i upario ga sa vraćanjem fokusa i provjerama pristupačnosti. To je najpouzdanija opcija, ali proračunsko vrijeme za dodatno ožičenje. Koristite fiksno pozicioniranje. Ovo je za kada ste u vanilla JavaScript-u ili laganom okviru i možete provjeriti da nijedan predak ne primjenjuje transformacije ili filtere. Jednostavan je za postavljanje i jednostavan za otklanjanje grešaka, sve dok postoji jedno ograničenje. Koristite CSS Anchor Positioning. Posegnite za ovo kada to dozvoli podrška vašeg pretraživača. Ako je potrebna Firefox podrška, uparite je sa @oddbird polyfill. Tu platforma u konačnici ide i na kraju će postati vaš pristup. Restrukturirajte DOM. Koristite ovo kada arhitektura to dozvoljava i ako želite nultu kompleksnost vremena izvođenja. Vjerujem da je to vjerovatno najpotcijenjenija opcija. Kombinujte obrasce. Uradite ovo kada želite pozicioniranje sidra kao svoj primarni pristup, upareno sa rezervnim JavaScript-om za nepodržane pretraživače. Ili portal za postavljanje DOM-a uparen sa getBoundingClientRect() za tačnost koordinata.

Zaključak Nekada sam ovu grešku tretirao kao jednokratnu stvar - nešto za zakrpiti i krenuti dalje. Ali kada sam se sa njim sedela dovoljno dugo da razumem sva tri uključena sistema – prelivanje, slaganje konteksta i sadržavanje blokova – prestao je da se oseća nasumično. Mogao sam pogledati pokvareni padajući meni i odmah pratiti koji je predak odgovoran. Ta promjena u načinu na koji sam čitao DOM bio je pravi zaključak. Ne postoji jedan tačan odgovor. Ono za čim sam posegnuo zavisilo je od onoga što sam mogao kontrolisati u bazi koda: portali kada je stablo predaka bilo nepredvidivo; fiksno pozicioniranje kada je bilo čisto i jednostavno; pomeranje elementa kada me ništa nije sprečavalo; i pozicioniranje sidra sada,gde mogu. Šta god na kraju odaberete, nemojte pristupačnost tretirati kao posljednji korak. Po mom iskustvu, to je tačno kada se preskoči. ARIA odnosi, upravljanje fokusom, ponašanje tastature - to nije uglađeno. Oni su dio onoga što čini da stvar zaista funkcionira. Pogledajte cijeli izvorni kod u mom GitHub repo. Dalje čitanje Ovo su reference kojima sam se stalno vraćao dok sam radio na ovome:

Kontekst slaganja (MDN) “CSS vodič za pozicioniranje sidra”, Juan Diego Rodriguez „Početak rada sa Popover API-jem“, Godstime Aburu Plutajuće korisničko sučelje (floating-ui.com) CSS overflow (MDN)

You May Also Like

Enjoyed This Article?

Get weekly tips on growing your audience and monetizing your content — straight to your inbox.

No spam. Join 138,000+ creators. Unsubscribe anytime.

Create Your Free Bio Page

Join 138,000+ creators on Seemless.

Get Started Free