Scenár je takmer vždy rovnaký, čo je dátová tabuľka vo vnútri rolovateľného kontajnera. Každý riadok má ponuku akcií, malú rozbaľovaciu ponuku s niektorými možnosťami, napríklad Upraviť, Duplikovať a Odstrániť. Keď ho postavíte, zdá sa, že funguje perfektne izolovane, a potom ho niekto vloží do rolovateľného divu a veci sa rozpadnú. Videl som presne túto chybu v troch rôznych kódových základniach: kontajner, zásobník a rámec, všetky rôzne. Chyba je však úplne identická. Rozbaľovacia ponuka sa odreže na okraji kontajnera. Alebo sa zobrazuje za obsahom, ktorý by mal byť logicky pod ním. Alebo to funguje dobre, kým sa používateľ neposunie, a potom sa posunie. Siahnete po z-indexe: 9999. Niekedy to pomôže, ale inokedy absolútne nič. Táto nekonzistentnosť je prvým náznakom toho, že sa deje niečo hlbšie. Dôvod, prečo sa to stále vracia, je, že sú zapojené tri samostatné systémy prehliadačov a väčšina vývojárov rozumie každému z nich samostatne, ale nikdy nepremýšľajú o tom, čo sa stane, keď sa všetky tri zrazia: pretečenie, skladanie kontextov a obsah blokov.

Keď pochopíte, ako sa všetky tri vzájomne ovplyvňujú, režimy zlyhania prestanú byť náhodné. V skutočnosti sa stávajú predvídateľnými. Tri veci, ktoré to skutočne spôsobujú Pozrime sa na každú z týchto položiek podrobne. Problém pretečenia Keď pre prvok nastavíte overflow: hidden, overflow: scroll alebo overflow: auto, prehliadač vystrihne všetko, čo presahuje jeho hranice, vrátane absolútne umiestnených potomkov. .scroll-container { prepad: auto; výška: 300px; /* Tým sa rozbaľovacia ponuka ostrihá, bodka */ }

.rozbaľovacia ponuka { pozícia: absolútna; /* Nezáleží na tom -- stále orezané .scroll-container */ }

To ma prekvapilo, keď som na to prvýkrát narazil. Zaujal som pozíciu: absolútna by umožnila prvku uniknúť výstrižku kontajnera. nie je. V praxi to znamená, že absolútne umiestnená ponuka môže byť odrezaná akýmkoľvek predkom, ktorý má neviditeľnú hodnotu pretečenia, aj keď tento predok nie je blokom ponuky. Clipovanie a polohovanie sú samostatné systémy. Náhodou sa zrazia spôsobmi, ktoré vyzerajú úplne náhodne, kým nepochopíte oboje.

Tu je príklad React pomocou createPortal:

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

function Dropdown({ anchorRef, isOpen, children }) { const [position, setPosition] = useState({ hore: 0, zľava: 0 });

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

if (!isOpen) return null;

vrátiť createPortal(

, dokument.telo ); }

A, samozrejme, nemôžeme ignorovať dostupnosť. Opravené prvky, ktoré sa zobrazujú nad obsahom, musia byť stále dostupné z klávesnice. Ak sa poradie zamerania prirodzene nepresunie do pevného rozbaľovacieho zoznamu, budete ho musieť spravovať pomocou kódu. Tiež stojí za to skontrolovať, či nesedí nad iným interaktívnym obsahom a nie je možné ho odmietnuť. Ten vás hryzie pri testovaní klávesnice. Umiestnenie kotvy CSS: Kam si myslím, že to smeruje CSS Anchor Positioning je smer, ktorý ma momentálne najviac zaujíma. Keď som sa na to prvýkrát pozrel, nebol som si istý, koľko špecifikácií bolo skutočne použiteľných. Umožňuje vám deklarovať vzťah medzi rozbaľovacím zoznamom a jeho spúšťačom priamo v CSS a prehliadač spracováva súradnice. .trigger { kotevné-meno: --my-trigger; }

.rozbaľovacia ponuka { pozícia: absolútna; poloha-kotva: --my-trigger; hore: kotva(dole); vľavo: kotva(vľavo); pozícia-skús-fallbacks: flip-block, flip-inline; }

Vlastnosť position-try-fallbacks je to, kvôli čomu sa oplatí použiť túto metódu pri manuálnom výpočte. Prehliadač skúša alternatívne umiestnenia skôr, ako to vzdá, takže rozbaľovacia ponuka v spodnej časti zobrazovanej oblasti sa namiesto orezania automaticky prevráti nahor. Podpora prehliadačov je stabilná v prehliadačoch založených na prehliadači Chromium a rastie v prehliadači Safari. Firefox potrebuje polyfill. Balík @oddbird/css-anchor-positioning pokrýva hlavnú špecifikáciu. Podarilo sa mi s ním naraziť na okrajové prípady rozloženia, ktoré si vyžadovali záložné riešenia, ktoré som nepredpokladal, takže to berte ako progresívne vylepšenie alebo ho spárujte sZáložný kód JavaScript pre Firefox. Skrátka sľubné, ale zatiaľ nie univerzálne. Otestujte vo svojich cieľových prehliadačoch. A pokiaľ ide o prístupnosť, deklarovanie vizuálneho vzťahu v CSS stromu prístupnosti nič nehovorí. aria-controls, aria-expanded, aria-haspopup — táto časť je stále na tebe. Niekedy Opravou stačí presunúť prvok Predtým, ako siahnem po portáli alebo urobím súradnicové výpočty, vždy si najprv položím jednu otázku: Musí tento rozbaľovací zoznam skutočne žiť vo vnútri rolovacieho kontajnera? Ak nie, presunom označenia do obalu vyššej úrovne sa problém úplne odstráni, bez JavaScriptu a bez výpočtov súradníc. Toto nie je vždy možné. Ak sú tlačidlo a rozbaľovacia ponuka zapuzdrené v rovnakom komponente, presun jedného bez druhého znamená prehodnotenie celého API. Ale keď to dokážete, nie je čo ladiť. Problém jednoducho neexistuje. Čo moderné CSS stále nerieši CSS tu prešlo dlhú cestu, ale stále existujú miesta, kde vás sklame. Pozícia: problémy s opravou a transformáciou stále existujú. Je to v špecifikácii zámerne, čo znamená, že neexistuje žiadne riešenie CSS. Ak používate knižnicu animácií, ktorá zabalí vaše rozloženie do transformovaného prvku, budete opäť potrebovať portály alebo umiestnenie kotvy. CSS Anchor Positioning je sľubné, ale nové. Ako už bolo spomenuté, Firefox v čase, keď to píšem, stále potrebuje polyfill. Narazil som na prípady okrajov rozloženia, ktoré si vyžadovali záložné riešenia, s ktorými som nerátal. Ak dnes potrebujete konzistentné správanie vo všetkých prehliadačoch, stále siahate po JavaScripte pre zložité časti. Doplnkom, pre ktorý som zmenil svoj pracovný postup, je rozhranie HTML Popover API, ktoré je teraz k dispozícii vo všetkých moderných prehliadačoch. Prvky s atribútom popover sa vykresľujú v hornej vrstve prehliadača, nad všetkým, bez potreby umiestňovania pomocou JavaScriptu.

Ovládanie únikov, odmietnutie kliknutím zvonka a solídna sémantika dostupnosti sú zadarmo pre veci, ako sú popisy, miniaplikácie na sprístupnenie informácií a jednoduché prekrytia. Je to prvý nástroj, po ktorom teraz siaham. To znamená, že to nerieši umiestnenie. Rieši vrstvenie. Na zarovnanie kontextového okna s jeho spúšťačom stále potrebujete umiestnenie kotvy alebo JavaScript. Rozhranie Popover API sa stará o vrstvenie. Umiestnenie kotvy rieši umiestnenie. Keď sa používajú spolu, pokrývajú väčšinu toho, čo ste predtým siahli po knižnici. Sprievodca rozhodovaním pre vašu situáciu Po tom, čo som si toto všetko prešiel ťažkou cestou, tu je návod, ako teraz skutočne premýšľam o výbere.

Použite portál. Použil by som to, keď spúšťač žije hlboko vo vnorených rolovacích kontajneroch. Tento vzor som použil pre ponuky akcií tabuľky a spároval som ho s obnovením zaostrenia a kontrolami dostupnosti. Je to najspoľahlivejšia možnosť, ale vyčleňte si čas na dodatočné vedenie. Použite pevné umiestnenie. Toto je, keď používate vanilkový JavaScript alebo zjednodušený rámec a môžete overiť, že žiadny predok nepoužíva transformácie ani filtre. Je jednoduché ho nastaviť a jednoducho ladiť, pokiaľ platí toto jedno obmedzenie. Použite CSS Anchor Positioning. Dosiahnite to, keď to podpora vášho prehliadača umožňuje. Ak je potrebná podpora Firefoxu, spárujte ju s @oddbird polyfill. Toto je miesto, kam platforma v konečnom dôsledku smeruje a nakoniec sa stane vaším hlavným prístupom. Reštrukturalizovať DOM. Použite to, keď to architektúra umožňuje a chcete nulovú zložitosť behu. Verím, že je to pravdepodobne najviac podceňovaná možnosť. Kombinujte vzory. Urobte to, keď chcete ako primárny prístup ukotvenie v spojení s záložným kódom JavaScript pre nepodporované prehliadače. Alebo portál pre umiestnenie DOM spárovaný s getBoundingClientRect() pre presnosť súradníc.

Záver Zvykol som túto chybu považovať za jednorazový problém - niečo, čo by sa dalo opraviť a pokračovať. Ale akonáhle som s ním sedel dostatočne dlho na to, aby som pochopil všetky tri zahrnuté systémy – orezávanie pretečenia, skladanie kontextov a obsah blokov – prestalo mi to pripadať ako náhodné. Mohol som sa pozrieť na nefunkčný rozbaľovací zoznam a okamžite zistiť, ktorý predok bol zodpovedný. Tento posun v tom, ako som čítal DOM, bol skutočným prínosom. Neexistuje jediná správna odpoveď. To, po čom som siahol, záviselo od toho, čo som mohol ovládať v kódovej základni: portály, keď bol strom predkov nepredvídateľný; pevné umiestnenie, keď to bolo čisté a jednoduché; pohyb prvku, keď ma nič nezastavilo; a umiestnenie kotvy teraz,kde môžem. Nech už si vyberiete čokoľvek, nepovažujte dostupnosť za posledný krok. Podľa mojich skúseností je to presne vtedy, keď sa to preskočí. Vzťahy ARIA, riadenie zamerania, správanie klávesnice – to nie je poľské. Sú súčasťou toho, vďaka čomu vec skutočne funguje. Pozrite si celý zdrojový kód v mojom úložisku GitHub. Ďalšie čítanie Toto sú referencie, ku ktorým som sa pri práci vracal:

Kontext stohovania (MDN) „Sprievodca polohovaním kotvy CSS“, Juan Diego Rodriguez „Začíname s Popover API“, Godstime Aburu Plávajúce používateľské rozhranie (floating-ui.com) Pretečenie CSS (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