სცენარი თითქმის ყოველთვის იგივეა, რაც არის მონაცემთა ცხრილი გადახვევის კონტეინერში. ყველა რიგს აქვს სამოქმედო მენიუ, პატარა ჩამოსაშლელი ჩამოსაშლელი რამდენიმე ვარიანტით, როგორიცაა რედაქტირება, დუბლიკატი და წაშლა. შენ ააშენებ მას, როგორც ჩანს, ის იდეალურად მუშაობს იზოლირებულად, შემდეგ კი ვიღაც აყენებს მას გადახვევად დივში და ნივთები იშლება. მე ვნახე ზუსტად ეს შეცდომა სამ სხვადასხვა კოდის ბაზაში: კონტეინერი, სტეკი და ჩარჩო, ყველა განსხვავებული. თუმცა, შეცდომა სრულიად იდენტურია. ჩამოსაშლელი მენიუ იჭრება კონტეინერის კიდეზე. ან ის ჩნდება შინაარსის უკან, რომელიც ლოგიკურად უნდა იყოს მის ქვემოთ. ან ის კარგად მუშაობს მანამ, სანამ მომხმარებელი არ გადახვევს, შემდეგ კი ის დრიფტდება. თქვენ მიაღწევთ z- ინდექსს: 9999. ხანდახან ეს გეხმარებათ, მაგრამ სხვა დროს ის აბსოლუტურად არაფერს აკეთებს. ეს შეუსაბამობა არის პირველი მინიშნება იმისა, რომ რაღაც უფრო ღრმა ხდება. მიზეზი ის არის, რომ ბრაუზერის სამი ცალკეული სისტემაა ჩართული და დეველოპერების უმეტესობას ესმის თითოეული დამოუკიდებლად, მაგრამ არასოდეს ფიქრობს იმაზე, თუ რა ხდება სამივე შეჯახებისას: გადადინება, კონტექსტების დაწყობა და ბლოკების შემცველი.

როგორც კი გაიგებთ, როგორ ურთიერთქმედებენ სამივე, წარუმატებლობის რეჟიმი წყვეტს შემთხვევითობის შეგრძნებას. სინამდვილეში, ისინი ხდებიან პროგნოზირებადი. სამი რამ, რაც რეალურად იწვევს ამას მოდით განვიხილოთ თითოეული ეს ელემენტი დეტალურად. გადახურების პრობლემა როდესაც ელემენტზე დააყენებთ overflow: დამალული, overflow: scroll ან overflow: auto, ბრაუზერი ამოიჭრება ყველაფერი, რაც სცილდება მის საზღვრებს, მათ შორის აბსოლუტურად განლაგებულ შთამომავლებს. .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;

დააბრუნეთ შექმნა პორტალი(

{ბავშვები}
, დოკუმენტი.სხეული ); }

და, რა თქმა უნდა, ჩვენ არ შეგვიძლია უგულებელვყოთ ხელმისაწვდომობა. ფიქსირებული ელემენტები, რომლებიც ჩნდება კონტენტზე, კვლავ ხელმისაწვდომი უნდა იყოს კლავიატურაზე. თუ ფოკუსის ბრძანება ბუნებრივად არ გადადის ფიქსირებულ ჩამოსაშლელ სიაში, თქვენ დაგჭირდებათ მისი მართვა კოდის გამოყენებით. ასევე ღირს იმის შემოწმება, რომ ის არ ჯდება სხვა ინტერაქტიულ შინაარსზე, მისი გაუქმების გარეშე. ის გკბენს კლავიატურის ტესტირებაში. CSS წამყვანის პოზიციონირება: მე ვფიქრობ, რომ ეს მიმართულია CSS წამყვანის პოზიციონირება არის ის მიმართულება, რომელიც ახლა ყველაზე მეტად მაინტერესებს. მე არ ვიცოდი, რამდენად იყო სპეციფიკაციის რეალურად გამოსაყენებელი, როდესაც პირველად შევხედე მას. ის საშუალებას გაძლევთ განაცხადოთ კავშირი ჩამოსაშლელ და მის ტრიგერს შორის პირდაპირ CSS-ში და ბრაუზერი ამუშავებს კოორდინატებს. .ტრიგერი { წამყვანი-სახელი: --ჩემი-ტრიგერი; }

.dropdown-menu { პოზიცია: აბსოლუტური; პოზიცია-წამყვანი: --ჩემი-ტრიგერი; ზედა: წამყვანი (ქვედა); მარცხენა: წამყვანი (მარცხნივ); position-try-fallbacks: flip-block, flip-inline; }

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 წამყვანის პოზიციონირება პერსპექტიული, მაგრამ ახალია. როგორც უკვე აღვნიშნეთ, Firefox-ს ჯერ კიდევ სჭირდება პოლიფილის შევსება, როცა ამას ვწერ. მე მასზე დავამარცხე განლაგების კიდეები, რომლებიც საჭიროებდა ჩანაცვლებებს, რომლებსაც არ ველოდი. თუ დღეს გჭირდებათ თანმიმდევრული ქცევა ყველა ბრაუზერში, თქვენ კვლავ ეძებთ JavaScript-ს რთული ნაწილებისთვის. დამატება, რომლისთვისაც რეალურად შევცვალე ჩემი სამუშაო პროცესი, არის HTML Popover API, რომელიც ახლა ხელმისაწვდომია ყველა თანამედროვე ბრაუზერში. ელემენტები popover ატრიბუტით გამოისახება ბრაუზერის ზედა ფენაში, უპირველეს ყოვლისა, JavaScript-ის პოზიციონირების საჭიროების გარეშე.

გაქცევის მართვა, გარედან დაწკაპუნებაზე გაუქმება და მყარი ხელმისაწვდომობის სემანტიკა უფასოა ისეთი ნივთებისთვის, როგორიცაა ინსტრუმენტების რჩევები, გამჟღავნების ვიჯეტები და მარტივი გადაფარვები. ეს არის პირველი ინსტრუმენტი, რომელსაც ახლა ვწვდები. ამის თქმით, ეს არ წყვეტს პოზიციონირებას. ის ხსნის ფენებს. თქვენ ჯერ კიდევ გჭირდებათ წამყვანის პოზიციონირება ან JavaScript პოპოვერის მის ტრიგერთან გასასწორებლად. Popover API მართავს ფენებს. წამყვანის პოზიციონირება ამუშავებს განთავსებას. ერთად გამოყენებული, ისინი ფარავს იმ ნაწილს, რისი გაკეთებაც ადრე გისურვეთ ბიბლიოთეკის გასაკეთებლად. გადაწყვეტილების გზამკვლევი თქვენი სიტუაციისთვის ამ ყველაფრის რთული გზის გავლის შემდეგ, აი, როგორ ვფიქრობ ახლა რეალურად არჩევანზე.

გამოიყენეთ პორტალი. მე ამას გამოვიყენებდი, როდესაც ტრიგერი ცხოვრობს ჩასმული გადახვევის კონტეინერებში. მე გამოვიყენე ეს ნიმუში ცხრილის მოქმედების მენიუსთვის და დავაკავშირე ფოკუსის აღდგენასა და ხელმისაწვდომობის შემოწმებებთან. ეს არის ყველაზე საიმედო ვარიანტი, მაგრამ ბიუჯეტის დრო დამატებითი გაყვანილობისთვის. გამოიყენეთ ფიქსირებული პოზიციონირება. ეს არის მაშინ, როდესაც თქვენ ხართ ვანილის JavaScript-ში ან მსუბუქ ჩარჩოში და შეგიძლიათ დაადასტუროთ, რომ წინაპარი არ იყენებს გარდაქმნებს ან ფილტრებს. მარტივია დაყენება და მარტივი გამართვა, სანამ ეს ერთი შეზღუდვა მოქმედებს. გამოიყენეთ CSS Anchor Positioning.მიაღწიეთ ამას, როდესაც თქვენი ბრაუზერის მხარდაჭერა ამის საშუალებას მოგცემთ. თუ Firefox-ის მხარდაჭერაა საჭირო, დააწყვილეთ იგი @oddbird პოლიფილთან. ეს არის ის, სადაც პლატფორმა საბოლოოდ მიდის და საბოლოოდ გახდება თქვენი მიდგომა. DOM-ის რესტრუქტურიზაცია. გამოიყენეთ ეს, როდესაც არქიტექტურა იძლევა ამის საშუალებას და თქვენ გსურთ ნულოვანი გაშვების სირთულე. მე მჯერა, რომ ეს ყველაზე დაუფასებელი ვარიანტია. შეუთავსეთ შაბლონები. გააკეთეთ ეს, როდესაც გსურთ წამყვანის პოზიციონირება, როგორც თქვენი ძირითადი მიდგომა, დაწყვილებული JavaScript-ის სარეზერვო საშუალებებთან მხარდაჭერილი ბრაუზერებისთვის. ან პორტალი DOM განთავსებისთვის, დაწყვილებული getBoundingClientRect() კოორდინატების სიზუსტისთვის.

დასკვნა ამ შეცდომას განვიხილავდი, როგორც ერთჯერად საკითხს - რაღაცას, რომლითაც უნდა გადავასწორო და გადავიდე. მაგრამ მას შემდეგ რაც საკმარისად დიდხანს ვიჯექი, რომ გავიგო ჩართული სამივე სისტემა - გადაჭარბებული ამოკვეთა, კონტექსტების დაწყობა და ბლოკების შემცველი - მან შეწყვიტა შემთხვევითობის შეგრძნება. მე შემეძლო გატეხილი ჩამოსაშლელი ჩანაწერის დათვალიერება და მაშინვე მიგვენახა, რომელი წინაპარი იყო პასუხისმგებელი. ეს ცვლილება იმაში, თუ როგორ ვკითხულობდი DOM-ს, იყო ნამდვილი წამალი. არ არსებობს ერთი სწორი პასუხი. რასაც მივაღწიე დამოკიდებული იყო იმაზე, რისი კონტროლი შემეძლო კოდების ბაზაში: პორტალები, როდესაც წინაპარი ხე არაპროგნოზირებადი იყო; ფიქსირებული პოზიციონირება, როდესაც ის იყო სუფთა და მარტივი; ელემენტის გადაადგილება, როცა არაფერი მაჩერებდა; და წამყვანის პოზიციონირება ახლა,სადაც შემიძლია. რასაც არ უნდა აირჩევთ, არ განიხილოთ ხელმისაწვდომობა, როგორც ბოლო ნაბიჯი. ჩემი გამოცდილებით, ეს არის ზუსტად მაშინ, როდესაც ის გამოტოვებულია. ARIA ურთიერთობები, ფოკუსის მენეჯმენტი, კლავიატურის ქცევა - ეს არ არის დახვეწილი. ისინი ნაწილია იმისა, რაც ნივთს რეალურად ამუშავებს. შეამოწმეთ სრული წყარო კოდი ჩემს GitHub რეპოში. შემდგომი კითხვა ეს არის ის ცნობები, რომლებზეც გამუდმებით ვუბრუნდებოდი ამ თემაზე მუშაობისას:

დაწყობის კონტექსტი (MDN) "CSS წამყვანის პოზიციონირების გზამკვლევი", ხუან დიეგო როდრიგესი "დაწყება Popover API-ით", Godstime Aburu მცურავი UI (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