Սցենարը գրեթե միշտ նույնն է, որը տվյալների աղյուսակ է պտտվող կոնտեյների ներսում: Յուրաքանչյուր տող ունի գործողությունների ընտրացանկ, փոքր բացվող ցանկ՝ որոշ ընտրանքներով, ինչպիսիք են Խմբագրել, Կրկնօրինակել և Ջնջել: Դուք կառուցում եք այն, թվում է, որ այն հիանալի աշխատում է առանձին, և հետո ինչ-որ մեկը այն դնում է պտտվող դիվի ներսում, և իրերը քանդվում են: Ես տեսել եմ այս ճշգրիտ սխալը երեք տարբեր կոդերի բազաներում՝ կոնտեյներ, կույտ և շրջանակ, բոլորը տարբեր են: Սխալը, սակայն, բոլորովին նույնական է: Բացվող ցանկը կտրվում է տարայի եզրին: Կամ այն ​​հայտնվում է բովանդակության հետևում, որը տրամաբանորեն պետք է լինի դրա տակ: Կամ այն ​​լավ է աշխատում, քանի դեռ օգտատերը չի պտտվում, այնուհետև այն շեղվում է: Դուք հասնում եք z-ինդեքսին՝ 9999: Երբեմն դա օգնում է, բայց երբեմն դա բացարձակապես ոչինչ չի անում: Այդ անհամապատասխանությունն առաջին հուշումն է, որ ավելի խորը բան է տեղի ունենում: Շարունակական վերադառնալու պատճառն այն է, որ ներգրավված են բրաուզերի երեք առանձին համակարգեր, և ծրագրավորողներից շատերը հասկանում են յուրաքանչյուրն ինքնուրույն, բայց երբեք չեն մտածում, թե ինչ է տեղի ունենում, երբ երեքն էլ բախվում են.

Երբ հասկանում եք, թե ինչպես են երեքն էլ փոխազդում, ձախողման ռեժիմները դադարում են պատահական զգալ: Իրականում դրանք դառնում են կանխատեսելի։ Երեք բաներ, որոնք իրականում դա են առաջացնում Եկեք մանրամասն նայենք այդ կետերից յուրաքանչյուրին: Հորդառատ խնդիրը Երբ տարրի վրա սահմանում եք արտահոսք՝ թաքնված, գերհեռացում՝ ոլորել կամ գերհեռացում՝ ավտոմատ, զննարկիչը կտրում է այն ամենը, ինչ դուրս է գալիս իր սահմաններից, ներառյալ բացարձակապես դիրքավորված ժառանգները: .scroll-container { արտահոսք `ավտոմատ; բարձրությունը՝ 300px; /* Սա կկտրի բացվող ցանկը, վերջակետ */ }

.բացվող { դիրքը `բացարձակ; /* Կարևոր չէ. դեռ կտրված է .scroll-container-ի կողմից */ }

Դա ինձ զարմացրեց առաջին անգամ, երբ հանդիպեցի դրան: Ես ենթադրում էի դիրք՝ բացարձակը թույլ կտա տարրին խուսափել տարայի հատվածից: Դա չի անում: Գործնականում դա նշանակում է, որ բացարձակապես տեղադրված ընտրացանկը կարող է կտրվել ցանկացած նախնիի կողմից, որն ունի անտեսանելի արտահոսքի արժեք, նույնիսկ եթե այդ նախնին մենյուի բլոկը չէ: Կտրումը և դիրքավորումը առանձին համակարգեր են: Նրանք պարզապես պատահականորեն բախվում են այնպիսի ձևերով, որոնք բոլորովին պատահական են թվում, մինչև չհասկանաք երկուսն էլ:

Ահա React-ի օրինակ՝ օգտագործելով createPortal-ը.

ներմուծել {createPortal } 'react-dom'-ից; ներմուծել { useState, useEffect, useRef } «react»-ից;

գործառույթը բացվող ({ 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]);

եթե (!isOpen) վերադարձնել null;

վերադարձնել createPortal (

{երեխաներ}
, փաստաթուղթ.մարմին ); }

Եվ, իհարկե, մենք չենք կարող անտեսել մատչելիությունը: Ֆիքսված տարրերը, որոնք հայտնվում են բովանդակության վրա, դեռևս պետք է հասանելի լինեն ստեղնաշարով: Եթե ​​ֆոկուսի կարգը բնականաբար չի տեղափոխվում ֆիքսված բացվող ցանկ, դուք պետք է այն կառավարեք՝ օգտագործելով կոդը: Արժե նաև ստուգել, ​​որ այն չի նստում այլ ինտերակտիվ բովանդակության վրա՝ առանց այն մերժելու: Այդ մեկը կծում է ձեզ ստեղնաշարի թեստավորման ժամանակ: CSS խարիսխի դիրքավորում. որտեղ ես կարծում եմ, որ սա ուղղվում է CSS Anchor Positioning-ը այն ուղղությունն է, որն ինձ ամենաշատն է հետաքրքրում այս պահին: Ես վստահ չէի, թե որքան մասն է իրականում օգտագործելի, երբ ես առաջին անգամ նայեցի դրան: Այն թույլ է տալիս Ձեզ հայտարարել բացվող ցանկի և դրա գործարկիչի միջև կապը անմիջապես CSS-ում, և զննարկիչը մշակում է կոորդինատները: .trigger { խարիսխ-անունը՝ --my-trigger; }

.dropdown-menu { դիրքը `բացարձակ; դիրք-խարիսխ. --my-trigger; վերևում `խարիսխ (ներքևում); ձախ: խարիսխ (ձախ); դիրք-փորձել-փակումներ. շրջել-բլոկ, շրջել-ինլայն; }

«Position-try-fallbacks» հատկությունն այն է, ինչն արժե այն օգտագործել ձեռքով հաշվարկով: Զննարկիչը փորձում է այլընտրանքային տեղաբաշխումներ նախքան հանձնվելը, այնպես որ տեսադաշտի ներքևում գտնվող բացվող ցանկն ինքնաբերաբար շրջվում է դեպի վեր՝ կտրվելու փոխարեն: Բրաուզերի աջակցությունը ամուր է Chromium-ի վրա հիմնված բրաուզերներում և աճում է Safari-ում: Firefox-ին անհրաժեշտ է պոլիֆիլմ: @oddbird/css-anchor-positioning փաթեթն ընդգրկում է հիմնական սպեկտրը: Ես դրա հետ հարվածել եմ դասավորության եզրային պատյաններ, որոնք պահանջում էին հետադարձ կապեր, որոնք ես չէի ակնկալում, այնպես որ վերաբերվեք այն որպես առաջադեմ բարելավում կամ զուգակցեք այնJavaScript-ի հետադարձ կապ Firefox-ի համար: Մի խոսքով, խոստումնալից, բայց դեռ ոչ ունիվերսալ: Փորձարկեք ձեր թիրախային բրաուզերներում: Իսկ ինչ վերաբերում է մատչելիությանը, ապա CSS-ում տեսողական հարաբերություններ հայտարարելը մատչելիության ծառին ոչինչ չի ասում: aria-controls, aria-expanded, aria-haspopup — այդ մասը դեռ ձեր վրա է: Երբեմն ուղղումը պարզապես տեղափոխում է տարրը Նախքան պորտալին հասնելը կամ կոորդինատային հաշվարկներ կատարելը, ես միշտ առաջին հերթին մեկ հարց եմ տալիս. Եթե ​​դա այդպես չէ, նշագծումը ավելի բարձր մակարդակի փաթաթան տեղափոխելը խնդիրն ամբողջությամբ կվերացնի՝ առանց JavaScript-ի և առանց կոորդինատների հաշվարկների: Սա միշտ չէ, որ հնարավոր է: Եթե ​​կոճակը և բացվող ցանկը պարփակված են նույն բաղադրիչի մեջ, մեկը առանց մյուսի տեղափոխելը նշանակում է վերաիմաստավորել ամբողջ API-ն: Բայց երբ դուք կարող եք դա անել, վրիպազերծելու բան չկա: Խնդիրը պարզապես գոյություն չունի. Այն, ինչ ժամանակակից CSS-ը դեռ չի լուծում CSS-ն այստեղ երկար ճանապարհ է անցել, բայց դեռ կան վայրեր, որոնք ձեզ հուսահատեցնում են: Դիրքորոշումը. ֆիքսված և փոխակերպվող խնդիրները դեռ կան: Դա միտումնավոր առկա է սպեկտրի մեջ, ինչը նշանակում է, որ CSS-ի լուծում գոյություն չունի: Եթե ​​դուք օգտագործում եք անիմացիոն գրադարան, որը փաթաթում է ձեր դասավորությունը փոխակերպված տարրի մեջ, դուք նորից պորտալների կամ խարիսխի դիրքավորման կարիք ունեք: CSS Anchor Positioning-ը խոստումնալից է, բայց նոր: Ինչպես նշվեց ավելի վաղ, Firefox-ը դեռևս կարիք ունի պոլիլցման այն պահին, երբ ես գրում եմ սա: Ես դրա հետ հարվածել եմ դասավորության եզրային պատյաններ, որոնք պահանջում էին հետադարձ կապեր, որոնք ես չէի կանխատեսում: Եթե ​​այսօր ձեզ անհրաժեշտ է հետևողական վարքագիծ բոլոր բրաուզերների մեջ, դուք դեռևս ձգտում եք JavaScript-ին բարդ մասերի համար: Հավելումը, որի համար իրականում փոխել եմ իմ աշխատանքային հոսքը, HTML Popover API-ն է, որն այժմ հասանելի է բոլոր ժամանակակից բրաուզերներում: Popover հատկանիշով տարրերը ցուցադրվում են բրաուզերի վերին շերտում, ամեն ինչից վեր, առանց JavaScript-ի դիրքավորման անհրաժեշտության:

Փախուստի կառավարումը, անջատումը սեղմելու վրա դրսից և ամուր հասանելիության իմաստաբանությունը անվճար են այնպիսի բաների համար, ինչպիսիք են գործիքների հուշումները, բացահայտման վիդջեթները և պարզ ծածկույթները: Դա առաջին գործիքն է, որին այժմ հասնում եմ: Ասել է թե՝ դա չի լուծում դիրքավորումը: Այն լուծում է շերտավորումը: Ձեզ դեռևս անհրաժեշտ է խարիսխի դիրքավորում կամ JavaScript՝ popover-ն իր ձգանին հավասարեցնելու համար: Popover API-ն կարգավորում է շերտավորումը: Խարիսխի դիրքավորումը կարգավորում է տեղադրումը: Միասին օգտագործված դրանք ընդգրկում են այն ամենի մեծ մասը, ինչ դուք նախկինում կհասնեիք գրադարանի համար: Որոշումների ուղեցույց ձեր իրավիճակի համար Այս ամենի միջով դժվար ճանապարհ անցնելուց հետո, ահա թե ինչպես եմ ես իրականում մտածում այժմ ընտրության մասին:

Օգտագործեք պորտալ: Ես դա կօգտագործեի, երբ ձգանն ապրում է ոլորման մեջ տեղադրված բեռնարկղերի խորքում: Ես օգտագործել եմ այս օրինաչափությունը սեղանի գործողությունների ընտրացանկերի համար և զուգակցել այն ֆոկուսի վերականգնման և հասանելիության ստուգումների հետ: Դա ամենահուսալի տարբերակն է, բայց բյուջետային ժամանակ է լրացուցիչ լարերի համար: Օգտագործեք ֆիքսված դիրքավորում: Սա այն դեպքում, երբ դուք գտնվում եք վանիլային JavaScript-ում կամ թեթև շրջանակում և չեք կարող հաստատել, որ որևէ նախահայր չի կիրառում փոխակերպումներ կամ զտիչներ: Պարզ է կարգավորելը և հեշտ է վրիպազերծել, քանի դեռ պահպանվում է այդ մեկ սահմանափակումը: Օգտագործեք CSS Anchor Positioning-ը: Հասեք դրան, երբ ձեր դիտարկիչի աջակցությունը դա թույլ է տալիս: Եթե ​​Firefox-ի աջակցությունը պահանջվում է, զուգակցեք այն @oddbird polyfill-ի հետ: Սա այն վայրն է, որտեղ հարթակը, ի վերջո, գնում է և ի վերջո կդառնա ձեր հիմնական մոտեցումը: Վերակազմավորեք DOM-ը: Օգտագործեք սա, երբ ճարտարապետությունը դա թույլ է տալիս, և դուք ցանկանում եք զրոյական գործարկման բարդություն: Կարծում եմ, որ դա, հավանաբար, ամենաթերագնահատված տարբերակն է: Միավորեք օրինաչափությունները: Դա արեք, երբ ցանկանում եք խարիսխի դիրքավորումը որպես ձեր առաջնային մոտեցում՝ զուգակցված JavaScript-ի հետադարձ կապի հետ չաջակցվող բրաուզերների համար: Կամ DOM-ի տեղադրման պորտալը, որը զուգակցված է getBoundingClientRect()-ի հետ՝ կոորդինատների ճշգրտության համար:

Եզրակացություն Ես այս վրիպակին վերաբերվում էի որպես միանվագ խնդրի՝ կարկատելու և դրանից առաջ շարժվելու մի բան: Բայց երբ ես բավական երկար նստեցի դրա հետ՝ հասկանալու համար, որ ներգրավված են բոլոր երեք համակարգերը՝ հորդառատ կտրում, համատեքստերի կուտակում և բլոկներ պարունակող, այն դադարեց պատահական զգալ: Ես կարող էի նայել կոտրված բացվող ցանկին և անմիջապես հետագծել, թե որ նախնին է պատասխանատու: Այդ փոփոխությունը, թե ինչպես էի կարդում DOM-ը, իրական միջոց էր: Մեկ ճիշտ պատասխան չկա. Այն, ինչին ես հասել էի, կախված էր նրանից, թե ինչ կարող էի կառավարել կոդերի բազայում. պորտալներ, երբ նախնի ծառը անկանխատեսելի էր. ֆիքսված դիրքավորում, երբ այն մաքուր և պարզ էր; շարժելով տարրը, երբ ինձ ոչինչ չէր խանգարում. և խարիսխի դիրքավորումն այժմ,որտեղ ես կարող եմ. Ինչ էլ որ ընտրեք, մի համարեք հասանելիությունը որպես վերջին քայլ: Իմ փորձով, դա հենց այն ժամանակ է, երբ այն բաց է թողնվում: ARIA-ի հարաբերությունները, ֆոկուսի կառավարումը, ստեղնաշարի վարքագիծը. Նրանք մաս են կազմում այն ​​բանի, ինչը ստիպում է իրականում աշխատել: Ստուգեք ամբողջական աղբյուրի կոդը իմ GitHub պահեստում: Հետագա ընթերցում Սրանք այն հղումներն են, որոնց ես անընդհատ վերադառնում էի այս միջոցով աշխատելիս.

Stacking Context (MDN) «CSS խարիսխի դիրքավորման ուղեցույց», Խուան Դիեգո Ռոդրիգես «Սկսել Popover API-ով», Godstime Aburu Լողացող միջերես (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