Scenarij je gotovo uvijek isti, a to je podatkovna tablica unutar spremnika koji se može pomicati. Svaki redak ima izbornik radnji, mali padajući izbornik s nekim opcijama, poput Uredi, Udvostruči i Izbriši. Napravite ga, čini se da savršeno funkcionira u izolaciji, a onda ga netko stavi u taj div koji se može pomicati i stvari se raspadnu. Vidio sam točno ovu pogrešku u tri različite baze koda: spremnik, stog i okvir, sve različite. Bug je, međutim, potpuno identičan. Padajući izbornik se šiša na rubu spremnika. Ili se pojavljuje iza sadržaja koji bi logično trebao biti ispod njega. Ili radi dobro dok se korisnik ne pomakne, a zatim se pomakne. Posežete za z-indexom: 9999. Ponekad pomaže, ali ponekad ne čini apsolutno ništa. Ta nedosljednost prvi je trag da se događa nešto dublje. Razlog zašto se stalno vraća je taj što su uključena tri odvojena sustava preglednika, a većina programera razumije svaki zasebno, ali nikada ne razmišljaju o tome što se događa kada se sva tri sudare: prelijevanje, slaganje konteksta i sadržavanje blokova.

Jednom kada shvatite kako sva tri međusobno djeluju, načini kvarova prestaju se činiti nasumičnima. Zapravo, postaju predvidljivi. Tri stvari koje to zapravo uzrokuju Pogledajmo svaku od tih stavki detaljno. Problem prelijevanja Kada postavite overflow: hidden, overflow: scroll ili overflow: auto na elementu, preglednik će izrezati sve što izlazi izvan njegovih granica, uključujući apsolutno pozicionirane potomke. .scroll-container { preljev: automatski; visina: 300px; /* Ovo će izrezati padajući izbornik, točka */ }

.padajući { pozicija: apsolutna; /* Nije važno -- još uvijek je ošišan .scroll-containerom */ }

To me iznenadilo kad sam prvi put naletio na to. Zauzeo sam stav: absolute bi dopustio elementu da izbjegne isječak spremnika. Ne čini se. U praksi to znači da apsolutno pozicionirani izbornik može biti odsječen bilo kojim prethodnikom koji ima nevidljivu vrijednost preljeva, čak i ako taj prethodnik nije blok koji sadrži izbornik. Rezanje i pozicioniranje odvojeni su sustavi. Samo se slučajno sudaraju na načine koji izgledaju potpuno nasumično dok ne shvatite oboje.

Evo primjera Reacta koji koristi createPortal:

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

funkcija Dropdown({ anchorRef, isOpen, children}) { const [position, setPosition] = useState({ top: 0, left: 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) return null;

vrati createPortal(

{djeca}
, dokument.tijelo ); }

I, naravno, ne možemo zanemariti pristupačnost. Fiksni elementi koji se pojavljuju preko sadržaja i dalje moraju biti dostupni tipkovnicom. Ako se redoslijed fokusa prirodno ne premjesti u fiksni padajući izbornik, morat ćete njime upravljati pomoću koda. Također je vrijedno provjeriti da ne stoji iznad drugog interaktivnog sadržaja bez mogućnosti da ga odbacite. Taj te grize u testiranju tipkovnice. Pozicioniranje CSS sidra: kamo mislim da ovo vodi CSS Anchor Positioning je smjer koji me trenutno najviše zanima. Nisam bio siguran koliko je specifikacija zapravo upotrebljivo kada sam ga prvi put pogledao. Omogućuje vam deklariranje odnosa između padajućeg izbornika i njegovog okidača izravno u CSS-u, a preglednik obrađuje koordinate. .okidač { ime-sidra: --moj-okidač; }

.padajući izbornik { pozicija: apsolutna; položaj-sidra: --moj-okidač; gore: sidro (dno); lijevo: sidro (lijevo); položaj-pokušaj-zamjene: flip-block, flip-inline; }

Svojstvo position-try-fallbacks je ono zbog čega se ovo isplati koristiti umjesto ručnog izračuna. Preglednik pokušava s alternativnim položajima prije nego što odustane, tako da se padajući izbornik na dnu okvira za prikaz automatski okreće prema gore umjesto da bude odrezan. Podrška preglednika je solidna u preglednicima temeljenim na Chromiumu i raste u Safariju. Firefox treba polifill. Paket @oddbird/css-anchor-positioning pokriva osnovne specifikacije. S njim sam pogodio rubne slučajeve izgleda koji su zahtijevali zamjenske mogućnosti koje nisam predvidio, pa ga tretirajte kao progresivno poboljšanje ili ga uparite sJavaScript zamjena za Firefox. Ukratko, obećavajuće, ali još ne univerzalno. Testirajte u ciljanim preglednicima. A što se pristupačnosti tiče, deklariranje vizualnog odnosa u CSS-u ne govori stablu pristupačnosti ništa. aria-controls, aria-expanded, aria-haspopup — taj je dio još uvijek na vama. Ponekad je popravak samo pomicanje elementa Prije nego posegnem za portalom ili napravim koordinatne izračune, uvijek prvo postavim jedno pitanje: Treba li ovaj padajući izbornik zapravo živjeti unutar spremnika za pomicanje? Ako se ne dogodi, premještanje oznake u omotač više razine u potpunosti uklanja problem, bez JavaScripta i izračunavanja koordinata. To nije uvijek moguće. Ako su gumb i padajući izbornik sadržani u istoj komponenti, pomicanje jednog bez drugog znači ponovno promišljanje cijelog API-ja. Ali kada to možete učiniti, nema se što otklanjati. Problem jednostavno ne postoji. Što moderni CSS još uvijek ne rješava CSS je ovdje daleko dogurao, ali još uvijek postoje mjesta na kojima vas iznevjeri. Položaj: problemi s popravljenim i transformiranim još uvijek postoje. To je u specifikaciji namjerno, što znači da ne postoji CSS zaobilazno rješenje. Ako koristite biblioteku animacija koja umotava vaš izgled u transformirani element, ponovno vam trebaju portali ili pozicioniranje sidra. CSS Anchor Positioning je obećavajuće, ali novo. Kao što je ranije spomenuto, Firefox još uvijek treba polifill u vrijeme kada ovo pišem. S njim sam pogodio rubne slučajeve rasporeda koji su zahtijevali pomoćne mogućnosti koje nisam predvidio. Ako vam je danas potrebno dosljedno ponašanje u svim preglednicima, još uvijek posežete za JavaScriptom za škakljive dijelove. Dodatak za koji sam zapravo promijenio tijek rada je HTML Popover API, sada dostupan u svim modernim preglednicima. Elementi s popover atributom prikazuju se u gornjem sloju preglednika, iznad svega, bez potrebe za JavaScript pozicioniranjem.

Rukovanje bijegom, odbacivanje pri kliku izvana i čvrsta semantika pristupačnosti dolaze besplatno za stvari kao što su opisi alata, widgeti za otkrivanje i jednostavni slojevi. To je prvi alat za kojim sam sada posegnuo. Ipak, to ne rješava pozicioniranje. Rješava slojevitost. I dalje vam je potrebno pozicioniranje sidra ili JavaScript za usklađivanje skočnog prozora s njegovim okidačem. Popover API upravlja slojevitošću. Pozicioniranje sidra upravlja postavljanjem. Kada se koriste zajedno, pokrivaju većinu onoga što biste prije posegnuli za knjižnicom. 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.

Upotrijebite portal. Koristio bih ovo kada okidač živi duboko u ugniježđenim spremnicima za pomicanje. Upotrijebio sam ovaj uzorak za radnje izbornika tablice i upario ga s vraćanjem fokusa i provjerama pristupačnosti. To je najpouzdanija opcija, ali odvojite vrijeme za dodatno ožičenje. Upotrijebite fiksno pozicioniranje. Ovo je za slučajeve kada ste u vanilla JavaScriptu ili laganom okviru i možete potvrditi da nijedan predak ne primjenjuje transformacije ili filtre. Jednostavan je za postavljanje i otklanjanje pogrešaka, sve dok postoji to jedno ograničenje. Koristite CSS Anchor Positioning. Posegnite za ovim kada to dopušta podrška vašeg preglednika. Ako je potrebna podrška za Firefox, uparite je s @oddbird polyfill. Ovo je kamo platforma konačno ide i na kraju će postati vaš pristup. Restrukturirajte DOM. Koristite ovo kada arhitektura to dopušta i želite nultu složenost vremena izvođenja. Vjerujem da je to vjerojatno najpodcijenjenija opcija. Kombinirajte uzorke. Učinite ovo kada želite pozicioniranje sidra kao svoj primarni pristup, uparen s rezervnim JavaScriptom za nepodržane preglednike. Ili portal za DOM položaj uparen s getBoundingClientRect() za točnost koordinata.

Zaključak Tretirao sam ovaj bug kao jednokratni problem — nešto što treba zakrpati i krenuti dalje. Ali nakon što sam sjedio s njim dovoljno dugo da shvatim sva tri uključena sustava - izrezivanje preljeva, slaganje konteksta i sadržavanje blokova - prestao se osjećati nasumično. Mogao sam pogledati pokvareni padajući izbornik i odmah pronaći koji je predak bio odgovoran. Ta promjena u načinu na koji sam čitao DOM bila je pravi zaključak. Ne postoji samo jedan pravi odgovor. Ono za čim sam posegnuo ovisilo je o tome što sam mogao kontrolirati u bazi koda: portali kada je stablo predaka bilo nepredvidljivo; fiksno pozicioniranje kada je bilo čisto i jednostavno; pomicanje elementa kada me ništa nije zaustavljalo; i pozicioniranje sidra sada,gdje mogu. Što god na kraju odabrali, pristupačnost nemojte smatrati posljednjim korakom. Po mom iskustvu, to je točno kada se preskoči. Odnosi ARIA, upravljanje fokusom, ponašanje tipkovnice - to nije dotjerano. Oni su dio onoga što čini da stvar zapravo funkcionira. Provjerite cijeli izvorni kod u mom GitHub repou. Daljnje čitanje Ovo su reference na koje sam se stalno vraćao dok sam radio na ovome:

Kontekst slaganja (MDN) “Vodič za pozicioniranje CSS sidra”, Juan Diego Rodriguez “Početak rada s 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