Senaryo neredeyse her zaman aynıdır; kaydırılabilir bir kabın içindeki veri tablosudur. Her satırda, bazı seçeneklerin bulunduğu küçük bir açılır menü olan bir eylem menüsü bulunur.DüzenlemekNo mess 'all." ifadesinde kullanıldığında, "Her şeyi temizledim. Kopyalamak, VeSilmek. Onu inşa ediyorsunuz, tek başına mükemmel çalışıyor gibi görünüyor ve sonra birisi onu kaydırılabilir şeyin içine koyuyordivve işler dağılır. Bu hatayı üç farklı kod tabanında gördüm: kapsayıcı, yığın ve çerçeve; hepsi farklı. Ancak hata tamamen aynı.
Açılır menü kabın kenarında kırpılır. Veya mantıksal olarak altında olması gereken içeriğin arkasında belirir. Veya kullanıcı ekranı kaydırana kadar iyi çalışır ve ardından kayar.
Ulaşırsınz-endeksi: 9999. Bazen yardımcı olur, ancak diğer zamanlarda kesinlikle hiçbir şey yapmaz. Bu tutarsızlık, daha derin bir şeyin gerçekleştiğinin ilk ipucudur.
Sürekli olarak geri gelmesinin nedeni, üç ayrı tarayıcı sisteminin dahil olması ve çoğu geliştiricinin her birini kendi başına anlaması ancak üçü çarpıştığında ne olacağını asla düşünmemesidir:taşmaNo mess 'all." ifadesinde kullanıldığında, "Her şeyi temizledim. bağlamları yığınlama, Veblok içeren.

Üçünün de nasıl etkileşimde bulunduğunu anladığınızda, başarısızlık modları rastgele hissetmeyi bırakır. Aslında tahmin edilebilir hale geliyorlar.
Aslında Buna Neden Olan Üç ŞeyBu öğelerin her birine ayrıntılı olarak bakalım.
Taşma Sorunu
Ayarladığınızdataşma: gizliNo mess 'all." ifadesinde kullanıldığında, "Her şeyi temizledim. taşma: kaydırma, veyataşma: otomatikTarayıcı, bir öğe üzerinde, kesinlikle konumlandırılmış alt öğeler de dahil olmak üzere, sınırlarının ötesine uzanan her şeyi kırpacaktır.
.scroll-konteyner {
taşma: otomatik;
yükseklik: 300 piksel;
/* Bu açılır menüyü kırpacaktır, tam durak */
}
.açılır {
konum: mutlak;
/* Önemli değil -- hala .scroll-container tarafından kırpılmış */
}
İlk karşılaştığımda bu beni şaşırttı. varsaymıştımkonum: mutlakbir öğenin bir kabın kırpılmasından kaçmasına izin verir. Değil.
Uygulamada bu, mutlak olarak konumlandırılmış bir menünün, görünür olmayan bir taşma değerine sahip herhangi bir ata tarafından kesilebileceği anlamına gelir; bu ata, menünün içerik bloğu olmasa bile. Kırpma ve konumlandırma ayrı sistemlerdir. Siz ikisini de anlayana kadar tamamen rastgele görünen şekillerde çarpışırlar.


İşte şunu kullanan bir React örneği:createPortal:
'react-dom'dan { createPortal }'ı içe aktarın;
'tepki'den { useState, useEffect, useRef }'i içe aktarın;
function Dropdown({ çapaRef, isOpen, çocuklar }) {
const [pozisyon, setPosition] = useState({ top: 0, left: 0 });
useEffect(() => {
if (isOpen && çapaRef.current) {
const rect = çapaRef.current.getBoundingClientRect();
setPosition({
üst: rect.bottom + window.scrollY,
sol: rect.left + window.scrollX,
});
}
}, [isOpen, çapaRef]);
if (!isOpen) null döndürür;
createPortal'a dön (
{çocuklar}
,
belge.gövdesi
);
}

Ve elbette erişilebilirliği de göz ardı edemeyiz. İçeriğin üzerinde görünen sabit öğeler yine de klavyeyle erişilebilir olmalıdır. Odaklanma sırası doğal olarak sabit açılır menüye taşınmazsa bunu kod kullanarak yönetmeniz gerekir. Ayrıca, onu göz ardı etmenin hiçbir yolu olmadan diğer etkileşimli içeriğin üzerine oturmadığını da kontrol etmeye değer. Bu, klavye testinde sizi ısırıyor.
CSS Bağlantı Konumlandırması: Bunun Nereye Gittiğini Düşünüyorum
CSS Bağlantı Konumlandırmasışu sıralar en çok ilgilendiğim yön. İlk baktığımda özelliğin ne kadarının gerçekten kullanılabilir olduğundan emin değildim. Bir açılır menü ile tetikleyicisi arasındaki ilişkiyi doğrudan CSS'de bildirmenize olanak tanır ve tarayıcı koordinatları yönetir.
.tetikleyici {
çapa-adı: --my-trigger;
}
.açılır menü {
konum: mutlak;
konum çapası: --my-trigger;
üst: çapa (alt);
sol: çapa (sol);
pozisyon-dene-geri dönüşler: flip-block, flip-inline;
}
. pozisyon-dene-geri dönüşlerözelliği bunu manuel hesaplamada kullanmaya değer kılan şeydir. Tarayıcı vazgeçmeden önce alternatif yerleşimleri dener, böylece görünümün altındaki açılır menü kesilmek yerine otomatik olarak yukarı doğru döner.
Tarayıcı desteği Chromium tabanlı tarayıcılarda sağlamdır ve Safari'de de büyümektedir. Firefox'un birçoklu doldurma.@oddbird/css-anchor-positioningpaket temel özellikleri kapsar. Beklemediğim geri dönüşler gerektiren uç düzen durumlarıyla karşılaştım, bu yüzden bunu aşamalı bir geliştirme olarak değerlendirin veya Firefox için bir JavaScript geri dönüşüyle eşleştirin.
Kısacası umut verici ama henüz evrensel değil. Hedef tarayıcılarınızda test edin.
Erişilebilirlik söz konusu olduğunda CSS'de görsel bir ilişki bildirmek erişilebilirlik ağacına hiçbir şey söylemez.aria-kontrolleriNo mess 'all." ifadesinde kullanıldığında, "Her şeyi temizledim. aria-genişletilmişNo mess 'all." ifadesinde kullanıldığında, "Her şeyi temizledim. aria-haspopup- bu kısım hala sana ait.
Bazen Çözüm Sadece Elemanı Hareket Ettirmektir
Bir portala ulaşmadan veya koordinat hesaplamaları yapmadan önce her zaman ilk olarak bir soru sorarım: Bu açılır menünün gerçekten kaydırma kabının içinde olması gerekiyor mu?
Aksi takdirde, işaretlemeyi daha yüksek düzeydeki bir sarmalayıcıya taşımak, hiçbir JavaScript ve koordinat hesaplaması olmadan sorunu tamamen ortadan kaldırır.
Bu her zaman mümkün değildir. Düğme ve açılır menü aynı bileşen içinde kapsüllenmişse, birini diğeri olmadan taşımak tüm API'yi yeniden düşünmek anlamına gelir. Ancak bunu yapabildiğinizde hata ayıklanacak hiçbir şey kalmaz. Sorun mevcut değil.
Modern CSS'nin Hala Çözemediği ŞeyCSS burada çok yol kat etti ama hâlâ sizi hayal kırıklığına uğrattığı yerler var.
. pozisyon: sabit ve dönüştürmeksorunlar hala mevcut. Spesifikasyonda kasıtlı olarak yer alıyor, bu da hiçbir CSS geçici çözümünün olmadığı anlamına geliyor. Mizanpajınızı dönüştürülmüş bir öğeye saran bir animasyon kitaplığı kullanıyorsanız, portallara veya bağlantı konumlandırmaya ihtiyaç duymaya geri dönersiniz.
CSS Bağlantı Konumlandırma umut vericidir ancak yenidir. Daha önce de belirtildiği gibi, Firefox'un hâlâ birçoklu doldurmabunu yazdığım sırada. Beklemediğim geri dönüşler gerektiren düzen uç durumlarına rastladım. Bugün tüm tarayıcılarda tutarlı davranışa ihtiyacınız varsa, zorlu kısımlar için hâlâ JavaScript'e ulaşıyorsunuz.
Aslında iş akışımı değiştirdiğim eklenti şu:HTML Popover API'si, artık tüm modern tarayıcılarda mevcut. Popover özelliğine sahip öğeler, herhangi bir JavaScript konumlandırması gerekmeden tarayıcının en üst katmanında, her şeyin üzerinde oluşturulur.
Popover içeriği
Kaçış yönetimi, dışarıdan tıklandığında kapatma ve sağlam erişilebilirlik semantiği, araç ipuçları, açıklama widget'ları ve basit katmanlar gibi şeyler için ücretsiz olarak gelir. Şimdilik ulaştığım ilk araç bu.
Bununla birlikte, konumlandırmayı çözmez. Katmanlamayı çözer. Bir popover'ı tetikleyicisine hizalamak için hala bağlantı konumlandırmaya veya JavaScript'e ihtiyacınız var. Popover API katmanlamayı yönetir. Çapa konumlandırma, yerleşimi yönetir. Birlikte kullanıldıklarında, daha önce bir kütüphanenin yapması gerekenlerin çoğunu kapsarlar.
Durumunuza Uygun Bir Karar RehberiTüm bunları zor yoldan geçtikten sonra, şimdi seçim hakkında aslında şu şekilde düşünüyorum.

- Bir portal kullanın.
Tetikleyici iç içe kaydırma kaplarının derinliklerinde yaşadığında bunu kullanırdım. Bu modeli tablo eylem menüleri için kullandım ve odak restorasyonu ve erişilebilirlik kontrolleriyle eşleştirdim. Bu en güvenilir seçenektir ancak ekstra kablolama için bütçe ayırmanız gerekir. - Sabit konumlandırma kullanın.
Bu, standart JavaScript veya hafif bir çerçevede olduğunuz ve hiçbir üst öğenin dönüşüm veya filtre uygulamadığını doğrulayamadığınız durumlar içindir. Tek bir kısıtlama geçerli olduğu sürece kurulumu basit ve hata ayıklaması kolaydır. - CSS Bağlantı Konumlandırmasını kullanın.
Tarayıcı desteğiniz izin verdiğinde buna ulaşın. Firefox desteği gerekiyorsa, bunu@oddbirdçoklu doldurma Platformun en sonunda yöneldiği ve en sonunda başvuracağınız yaklaşım haline geleceği yer burasıdır. - DOM'u yeniden yapılandırın.
Mimari izin verdiğinde ve sıfır çalışma zamanı karmaşıklığı istiyorsanız bunu kullanın. Bunun muhtemelen en küçümsenen seçenek olduğuna inanıyorum. - Desenleri birleştirin.
Desteklenmeyen tarayıcılar için bir JavaScript geri dönüşüyle birlikte bağlantı konumlandırmanın birincil yaklaşımınız olmasını istiyorsanız bunu yapın. Veya DOM yerleşimi için eşleştirilmiş bir portalgetBoundingClientRect()Koordinat doğruluğu için.
Bu hatayı tek seferlik bir sorun olarak ele alırdım; yama yapılması ve devam edilmesi gereken bir şey. Ancak, ilgili üç sistemi de anlayacak kadar uzun süre onunla oturduktan sonra -taşma kırpmaNo mess 'all." ifadesinde kullanıldığında, "Her şeyi temizledim. bağlamları yığınlama, Veblok içeren- rastgele hissetmeyi bıraktı. Bozuk bir açılır listeye bakabilir ve hangi atanın sorumlu olduğunu hemen izleyebilirim. DOM'u okuma şeklimdeki bu değişiklik asıl çıkarım oldu.
Tek bir doğru cevap yok. Ulaştığım şey kod tabanında neyi kontrol edebildiğime bağlıydı: ata ağacının öngörülemez olduğu durumlarda portallar; temiz ve basit olduğunda sabit konumlandırma; hiçbir şey beni durduramazken elementi hareket ettirmek; ve şimdi mümkün olan her yerde çapayı konumlandırıyorum.
Sonunda ne seçersen seç,Erişilebilirliği son adım olarak görmeyin. Tecrübelerime göre tam da bu noktada atlanıyor. ARIA ilişkileri, odak yönetimi, klavye davranışı; bunlar pek cilalı değil. Bir şeyin gerçekten işe yaramasını sağlayan şeyin bir parçası bunlar.
Kaynak kodunun tamamına göz atınGitHub depom.
Ek Okuma
Bunlar üzerinde çalışırken sürekli olarak başvurduğum referanslar:
- Yığınlama Bağlamı(MDN)
- “CSS Bağlantı Konumlandırma Kılavuzu”, Juan Diego Rodriguez
- “Popover API'sine Başlarken”, Tanrı aşkına Aburu
- Kayan kullanıcı arayüzü(yüzen-ui.com)
- CSS Taşması(MDN)




