Сценарий дээрлик дайыма бирдей, бул сыдырма контейнердин ичиндеги маалымат таблицасы. Ар бир сапта аракет менюсу, Түзөтүү, Кайталоо жана Жок кылуу сыяктуу кээ бир параметрлери бар чакан ачылуучу тизме бар. Сиз аны курасыз, ал өзүнчө мыкты иштейт окшойт, анан кимдир бирөө аны ошол жылдырылуучу divдин ичине киргизип, нерселер ыдырап кетет. Мен бул так мүчүлүштүктөрдү үч түрдүү код базасында көрдүм: контейнер, стек жана алкак, бардыгы ар башка. Бирок мүчүлүштүктөр толугу менен окшош. Ашылма тизме контейнердин четинде кесилет. Же логикалык жактан төмөн болушу керек болгон мазмундун артында көрүнөт. Же ал колдонуучу сыдырмайынча жакшы иштейт, андан кийин ал дрейфке кетет. Сиз z-индексине жетесиз: 9999. Кээде бул жардам берет, бирок башка учурларда ал эч нерсе кылбайт. Бул карама-каршылык тереңирээк бир нерсе болуп жатканынын биринчи белгиси. Анын кайталанып келе жатышынын себеби, үч өзүнчө браузер системасы тартылган жана көпчүлүк иштеп чыгуучулар ар бирин өз алдынча түшүнүшөт, бирок үчөө тең кагылышканда эмне болору жөнүндө эч качан ойлошпойт: толуп кетүү, контексттерди топтоо жана блокторду камтыган.
Үчөө тең кандайча өз ара аракеттенишээрин түшүнгөндөн кийин, ката режимдери кокустук сезимин токтотот. Чынында, алар алдын ала болуп калат. Чынында буга себеп болгон үч нерсе Келгиле, майда-чүйдөсүнө чейин ошол нерселердин ар бирин карап көрөлү. Толуп кетүү көйгөйү Элементке overflow: hidden, overflow: scroll же overflow: auto орнотконуңузда, браузер анын чегинен ашкан нерселердин баарын, анын ичинде абсолюттук жайгаштырылган урпактарды кыркып салат. .scroll-container { толуп кетүү: авто; бийиктиги: 300px; /* Бул ылдыйкы ылдыйда, чекитте */ }
.ашылма { позициясы: абсолюттук; /* Маанилүү эмес -- дагы эле .scroll-container тарабынан кесилген */ }
Мен аны биринчи жолу көргөндө таң калдым. Мен позицияны кабыл алчумун: абсолюттук элементтин контейнердин кесилишинен качууга мүмкүндүк берет. Андай эмес. Иш жүзүндө, бул абсолюттук жайгаштырылган менюну көзгө көрүнбөгөн ашыкча мааниге ээ болгон ар кандай ата-бабадан кесип салышы мүмкүн дегенди билдирет, ал тургай, ал ата-баба менюда камтылган блок болбосо да. Клип алуу жана жайгаштыруу өзүнчө системалар. Экөөнү тең түшүнгөнгө чейин алар такыр эле кокусунан көрүнгөн жол менен кагылышат.
Бул жерде createPortal колдонгон React мисалы:
{createPortal} 'react-dom'дан импорттоо; import { useState, useEffect, useRef } 'реакциядан';
Функция Ашылма ({anchorRef, isOpen, балдар }) { const [позиция, setPosition] = useState({жогорку: 0, сол: 0});
useEffect(() => { if (isOpen && anchorRef.current) { const rect = anchorRef.current.getBoundingClientRect(); setPosition({ үстү: rect.bottom + window.scrollY, сол: rect.left + window.scrollX, }); } }, [isOpen, anchorRef]);
if (!isOpen) return null;
CreatePortal(
Анан, албетте, биз жеткиликтүүлүктү четке кага албайбыз. Мазмундун үстүндө пайда болгон туруктуу элементтер дагы эле клавиатурада жеткиликтүү болушу керек. Фокус тартиби табигый түрдө белгиленген ылдыйкы тизмеге өтпөсө, аны код менен башкаруу керек болот. Ал ошондой эле башка интерактивдүү мазмундун үстүнөн отурбагандыгын текшерүү керек, аны четке кагуу үчүн эч кандай жол жок. Бул клавиатураны текшерүүдө сизди тиштеп алат. CSS Anchor Positioning: Бул кайда баратат деп ойлойм CSS Anchor Positioning - бул мени азыр эң кызыктырган багыт. Мен аны биринчи жолу караганымда, спецификациянын канчасы чындыгында колдонууга болоорун билген эмесмин. Бул ылдый түшүүчү тизме менен анын триггеринин ортосундагы мамилени түздөн-түз CSSде жарыялоого мүмкүндүк берет жана браузер координаттарды иштетет. .триггер { anchor-name: --my-trigger; }
.ашылуучу меню { позициясы: абсолюттук; position-anchor: --my-trigger; үстү: казык (төмөнкү); солго: казык (сол); позиция-тырыш-кайтаруулар: флип-блок, флип-inline; }
Pozisyon-try-fallbacks касиети муну кол менен эсептөөдө колдонууга арзырлык кылат. Браузер баш тартуудан мурун альтернативдик жайгаштырууга аракет кылат, андыктан көрүү портунун ылдый жагындагы ачылуучу тизме үзүлбөй, автоматтык түрдө жогору карай бурулат. Браузерди колдоо Chromium негизделген браузерлерде бекем жана Safariде өсүүдө. Firefox көп толтуруу керек. @oddbird/css-anchor-positioning пакети негизги спецификацияны камтыйт. Мен аны менен мен күтпөгөн жаңылыштыктарды талап кылган макеттин четине чыктым, андыктан аны прогрессивдүү өркүндөтүү катары караңыз же аныFirefox үчүн JavaScript кайтаруу. Кыскасы, келечектүү, бирок азырынча универсалдуу эмес. Максаттуу браузерлериңизде сынап көрүңүз. Ал эми жеткиликтүүлүккө келсек, CSSде визуалдык байланышты жарыялоо жеткиликтүүлүк дарагына эч нерсе билдирбейт. aria-controls, aria-expanded, aria-haspopup - бул бөлүк дагы эле сизде. Кээде оңдоо жөн гана элементти жылдырып жатат Порталга же координаттарды эсептөөдөн мурун, мен ар дайым биринчи суроону берем: Бул ачылуучу тизме чындыгында жылдыргыч контейнердин ичинде жашашы керекпи? Антпесе, белгини жогорку деңгээлдеги орогучка жылдыруу JavaScript жана координаттарды эсептөөлөрсүз көйгөйдү толугу менен жок кылат. Бул дайыма эле мүмкүн боло бербейт. Эгер баскыч жана ачылуучу тизме бир эле компонентте камтылган болсо, бирин экинчисисиз жылдыруу бүт APIди кайра карап чыгууну билдирет. Бирок сиз муну кыла алганыңызда, мүчүлүштүктөрдү оңдоо үчүн эч нерсе жок. көйгөй жөн эле жок. Заманбап CSS эмнени чечпейт CSS бул жерде көп жолду басып өттү, бирок дагы эле сизди капа кылган жерлер бар. Позиция: белгиленген жана трансформация маселелери дагы эле бар. Бул атайын спецификацияда, бул эч кандай CSS чечүүчү жол жок дегенди билдирет. Эгер сиз макетиңизди өзгөртүлгөн элементке ороп турган анимация китепканасын колдонуп жатсаңыз, сизге порталдар же казыктарды жайгаштыруу керек болуп жатат. CSS Anchor Positioning келечектүү, бирок жаңы. Жогоруда айтылгандай, мен муну жазып жаткан учурда Firefox дагы эле көп толтурууга муктаж. Мен аны менен мен күтпөгөн жаңылыштыктарды талап кылган макеттин четине чыктым. Бүгүнкү күндө бардык браузерлерде ырааттуу жүрүм-турум керек болсо, сиз дагы эле татаал бөлүктөрү үчүн JavaScript издеп жатасыз. Мен чындыгында жумуш процессимди өзгөрткөн кошумча нерсе бул HTML Popover API, азыр бардык заманбап браузерлерде жеткиликтүү. Popover атрибуту бар элементтер браузердин үстүнкү катмарында, баарынан жогору, JavaScript позициясын талап кылбайт.
Башкаруудан качуу, чыкылдатканда четке кагуу жана катуу жеткиликтүүлүк семантикасы куралдар кеңештери, ачыкка чыгаруу виджеттери жана жөнөкөй катмарлар үчүн бекер келет. Бул мен азыр жеткен биринчи курал. Айтор, бул позицияны чечпейт. Ал катмарлоону чечет. Поповерди анын триггерине тегиздөө үчүн сизге анкердин жайгашуусу же JavaScript керектелет. Popover API катмарлоону башкарат. Анкердин жайгашуусу жайгаштырууну башкарат. Чогуу колдонулганда, алар китепканага мурда жеткен нерселердин көбүн камтыйт. Сиздин кырдаал үчүн чечим колдонмо Мунун баарын башынан өткөргөндөн кийин, мен азыр тандоо жөнүндө кандай ойдомун.
Порталды колдонуңуз. Мен муну триггер уя салынган сыдырма контейнерлердин тереңинде жашаганда колдоном. Мен бул үлгүнү столдун аракет менюсу үчүн колдондум жана аны фокусту калыбына келтирүү жана жеткиликтүүлүк текшерүүлөрү менен жупташтырдым. Бул эң ишенимдүү вариант, бирок кошумча зымдар үчүн бюджеттик убакыт. Туруктуу жайгаштыруу функциясын колдонуңуз. Бул ванильдүү JavaScript же жеңил алкакта болгондо жана эч бир ата-баба трансформацияларды же чыпкаларды колдонбогондугун текшере албаганыңыз үчүн. Орнотуу оңой жана мүчүлүштүктөрдү оңдоо оңой, эгерде ошол бир чектөө болсо. Бул үчүн CSS Anchor Positioning.Reach колдонуңуз. Firefox колдоосу керек болсо, аны @oddbird polyfill менен жупташтырыңыз. Бул платформа акырында баратат жана бара-бара сиздин мамилеңизге айланат. DOMды реструктуризациялаңыз. Архитектура уруксат бергенде муну колдонуңуз жана сиз нөл иштөө убактысынын татаалдыгын кааласаңыз. Мен бул эң төмөн бааланган вариант деп эсептейм. Үлгүлөрдү бириктириңиз. Колдоого алынбаган браузерлер үчүн JavaScript резерви менен жупташтырылган негизги ыкма катары анкердин жайгашуусун кааласаңыз, муну жасаңыз. Же координаттардын тактыгы үчүн getBoundingClientRect() менен жупташкан DOM жайгаштыруу порталы.
Корутунду Мен бул мүчүлүштүктөрдү бир жолку маселе катары карачумун — аны оңдоо жана андан ары улантуу. Бирок мен аны менен үч системаны тең түшүнүү үчүн жетиштүү убакыт отургандан кийин - ашыкча кыркып алуу, контексттерди топтоо жана блокторду камтыган - ал кокустук сезимин токтотту. Мен сынган ачылуучу тизмени карап, кайсы ата-баба жооптуу экенин дароо байкадым. Мен DOMды окуудагы бул өзгөрүү чыныгы алып баруу болду. Бир туура жооп жок. Мен эмнеге жетиштим, код базасында эмнени көзөмөлдөй алам деп көз каранды болдум: ата-баба дарагы күтүүсүз болгон порталдар; таза жана жөнөкөй болгондо туруктуу жайгаштыруу; мени эч нерсе токтотпогондо элементти жылдыруу; жана казык жайгаштыруу азыр,мен кайда. Эмнени тандабаңыз, жеткиликтүүлүктү акыркы кадам катары карабаңыз. Менин тажрыйбам боюнча, ал так ошол учурда өтүп кетет. ARIA мамилелери, фокусту башкаруу, клавиатуранын жүрүм-туруму - булар жылтырабайт. Алар нерсенин чындыгында иштешин камсыз кылган нерселердин бир бөлүгү. Менин GitHub реподагы толук баштапкы кодду текшериңиз. Андан ары окуу Булар менен иштөөдө мен кайра кайрылып келе жаткан шилтемелер:
Stacking Context (MDN) "CSS Anchor Positioning Guide", Хуан Диего Родригес "Popover API менен баштоо", Godstime Aburu Floating UI (floating-ui.com) CSS Overflow (MDN)