سناریو تقریباً همیشه یکسان است، که یک جدول داده در داخل یک ظرف قابل پیمایش است. هر ردیف دارای یک منوی عمل است، یک منوی کشویی کوچک با برخی از گزینه ها، مانند ویرایش، تکرار، و حذف. شما آن را می‌سازید، به نظر می‌رسد که کاملاً مجزا کار می‌کند، و سپس کسی آن را داخل آن div قابل پیمایش قرار می‌دهد و همه چیز از هم می‌پاشد. من دقیقاً این باگ را در سه پایگاه کد مختلف دیده‌ام: ظرف، پشته و چارچوب، همه متفاوت است. با این حال، اشکال کاملاً یکسان است. منوی کشویی در لبه ظرف بریده می شود. یا پشت محتوایی ظاهر می شود که منطقاً باید زیر آن باشد. یا تا زمانی که کاربر اسکرول نکند خوب کار می کند و سپس دریفت می کند. شما به z-index دست پیدا می کنید: 9999. گاهی اوقات کمک می کند، اما گاهی اوقات مطلقاً هیچ کاری نمی کند. این ناهماهنگی اولین سرنخ است که نشان می دهد اتفاق عمیق تری در حال رخ دادن است. دلیل بازگشت مجدد آن این است که سه سیستم مرورگر مجزا درگیر هستند و اکثر توسعه دهندگان هر کدام را به تنهایی درک می کنند اما هرگز به این فکر نمی کنند که وقتی هر سه با هم برخورد می کنند چه اتفاقی می افتد: سرریز، انباشتن زمینه ها و بلوک های حاوی.

هنگامی که درک کردید که هر سه چگونه با هم تعامل دارند، حالت های شکست احساس تصادفی نمی کنند. در واقع آنها قابل پیش بینی می شوند. سه چیز در واقع باعث این می شود بیایید هر یک از آن موارد را با جزئیات بررسی کنیم. مشکل سرریز وقتی سرریز: پنهان، سرریز: اسکرول یا سرریز: خودکار را روی یک عنصر تنظیم می‌کنید، مرورگر هر چیزی را که فراتر از محدوده‌های آن باشد، از جمله نوادگان کاملاً موقعیت‌یافته را برش می‌دهد. .scroll-container { سرریز: خودکار; ارتفاع: 300 پیکسل؛ /* این منوی کرکره ای، نقطه پایان را بریده می کند */ }

کشویی { موقعیت: مطلق; /* مهم نیست -- هنوز توسط .scroll-container بریده شده */ }

اولین باری که با آن برخورد کردم مرا شگفت زده کرد. من موقعیت را فرض می‌کردم: مطلق به عنصری اجازه می‌دهد از بریدگی ظرف فرار کند. ندارد. در عمل، این بدان معناست که یک منوی کاملاً دارای موقعیت می‌تواند توسط هر اجدادی که دارای مقدار سرریز غیرقابل مشاهده است، قطع شود، حتی اگر آن جد بلوک حاوی منو نباشد. برش و موقعیت یابی سیستم های جداگانه ای هستند. آنها فقط به شکلی کاملا تصادفی با هم برخورد می کنند تا زمانی که شما هر دو را درک کنید.

در اینجا یک مثال React با استفاده از createPortal آورده شده است:

وارد کردن {createPortal } از 'react-dom'; وارد کردن { useState, useEffect, useRef } از 'react';

تابع کشویی ({ anchorRef، isOpen، کودکان }) { const [position, setPosition] = useState({ top: 0, left: 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 Anchor Positioning: من فکر می کنم به کجا می رود CSS Anchor Positioning جهتی است که در حال حاضر بیشتر به آن علاقه دارم. وقتی برای اولین بار به آن نگاه کردم مطمئن نبودم چقدر از مشخصات واقعا قابل استفاده است. این به شما امکان می دهد رابطه بین یک کشویی و ماشه آن را مستقیماً در CSS اعلام کنید و مرورگر مختصات را مدیریت می کند. ماشه { anchor-name: --my-trigger; }

منوی کشویی { موقعیت: مطلق; position-anchor: --my-trigger; بالا: لنگر (پایین)؛ چپ: لنگر (سمت چپ); موقعیت-تلاش-fallbacks: flip-block، flip-inline; }

ویژگی position-try-fallbacks چیزی است که ارزش استفاده از این را در یک محاسبه دستی دارد. مرورگر قبل از تسلیم شدن، مکان‌های جایگزین را امتحان می‌کند، بنابراین یک منوی کشویی در پایین پنجره دید به‌جای قطع شدن، به‌طور خودکار به سمت بالا حرکت می‌کند. پشتیبانی از مرورگر در مرورگرهای مبتنی بر Chromium قوی است و در Safari در حال رشد است. فایرفاکس نیاز به پلی پر دارد. بسته @oddbird/css-anchor-positioning مشخصات هسته را پوشش می دهد. من موارد لبه طرح‌بندی را با آن زده‌ام که نیاز به بازگشت‌هایی داشت که پیش‌بینی نمی‌کردم، بنابراین آن را به‌عنوان یک پیشرفت پیشرونده در نظر بگیرید یا آن را با یک جفت کنید.جایگزینی جاوا اسکریپت برای فایرفاکس. به طور خلاصه، امیدوار کننده اما هنوز جهانی نیست. در مرورگرهای هدف خود تست کنید. و تا آنجا که به دسترسی مربوط می شود، اعلام یک رابطه بصری در CSS چیزی به درخت دسترسی نمی گوید. aria-controls، aria-expanded، aria-haspopup - آن قسمت هنوز بر عهده شماست. گاهی اوقات راه حل فقط عنصر را جابجا می کند قبل از دستیابی به پورتال یا انجام محاسبات مختصات، همیشه ابتدا یک سوال می‌پرسم: آیا این فهرست کشویی واقعاً باید در داخل محفظه اسکرول زندگی کند؟ اگر اینطور نیست، انتقال نشانه‌گذاری به یک پوشش سطح بالاتر، بدون جاوا اسکریپت و بدون محاسبه مختصات، مشکل را به طور کامل برطرف می‌کند. این همیشه امکان پذیر نیست اگر دکمه و منوی کشویی در یک جزء محصور شده باشند، جابجایی یکی بدون دیگری به معنای بازنگری در کل API است. اما وقتی بتوانید این کار را انجام دهید، چیزی برای رفع اشکال وجود ندارد. مشکل فقط وجود ندارد آنچه CSS مدرن هنوز حل نمی کند CSS در اینجا راه طولانی را پیموده است، اما هنوز جاهایی وجود دارد که شما را ناامید می کند. موقعیت: مسائل ثابت و تبدیل هنوز وجود دارد. این به طور عمدی در مشخصات است، به این معنی که هیچ راه حلی برای CSS وجود ندارد. اگر از یک کتابخانه انیمیشن استفاده می‌کنید که چیدمان شما را در یک عنصر تغییر شکل داده شده می‌پیچد، به پورتال یا موقعیت لنگر نیاز دارید. CSS Anchor Positioning امیدوارکننده، اما جدید است. همانطور که قبلاً ذکر شد، فایرفاکس هنوز در زمانی که من این مطلب را می نویسم به پلی پر نیاز دارد. من موارد لبه layout را با آن زدم که به عقب‌نشینی‌هایی نیاز داشت که پیش‌بینی نمی‌کردم. اگر امروز به رفتار ثابت در همه مرورگرها نیاز دارید، هنوز هم به دنبال جاوا اسکریپت برای بخش های مشکل هستید. افزونه‌ای که من در واقع گردش کار خود را برای آن تغییر داده‌ام، HTML Popover API است که اکنون در همه مرورگرهای مدرن موجود است. عناصر با ویژگی popover در لایه بالایی مرورگر، بالاتر از همه چیز، بدون نیاز به موقعیت یابی جاوا اسکریپت ارائه می شوند.

مدیریت فرار، رد کردن روی کلیک در خارج، و معناشناسی دسترسی کامل برای مواردی مانند نکات ابزار، ویجت‌های افشا، و پوشش‌های ساده رایگان است. این اولین ابزاری است که در حال حاضر به آن دست پیدا می کنم. گفته می شود، موقعیت یابی را حل نمی کند. لایه بندی را حل می کند. شما همچنان به موقعیت یابی لنگر یا جاوا اسکریپت برای تراز کردن پاپاور با ماشه آن نیاز دارید. Popover API لایه بندی را مدیریت می کند. موقعیت لنگر قرار دادن را کنترل می کند. با هم استفاده می‌شوند، آنها بیشتر کارهایی را که قبلاً برای انجام یک کتابخانه می‌خواستید پوشش می‌دهند. راهنمای تصمیم گیری برای موقعیت شما بعد از گذراندن همه اینها به سختی، در اینجا نحوه فکر کردن من در مورد انتخاب است.

از یک پورتال استفاده کنید. زمانی که ماشه در ظروف اسکرول تو در تو زندگی می کند، از آن استفاده می کنم. من از این الگو برای منوهای عملکرد جدول استفاده کردم و آن را با بازیابی فوکوس و بررسی دسترسی جفت کردم. این قابل اطمینان ترین گزینه است، اما برای سیم کشی اضافی زمان صرف می کند. از موقعیت‌یابی ثابت استفاده کنید. این برای زمانی است که در جاوا اسکریپت وانیلی یا یک چارچوب سبک وزن هستید و نمی‌توانید تأیید کنید که هیچ اجدادی تبدیل یا فیلتر را اعمال نکرده است. راه‌اندازی آن ساده و اشکال‌زدایی آن ساده است، تا زمانی که آن یک محدودیت وجود داشته باشد. از CSS Anchor Positioning استفاده کنید. زمانی که پشتیبانی مرورگر شما اجازه می دهد به این کار دست پیدا کنید. اگر پشتیبانی فایرفاکس مورد نیاز است، آن را با polyfill @oddbird جفت کنید. این همان جایی است که پلتفرم در نهایت در حال حرکت است و در نهایت به رویکرد شما تبدیل خواهد شد. DOM را بازسازی کنید. وقتی معماری اجازه می دهد از این استفاده کنید و پیچیدگی زمان اجرا را صفر می خواهید. من معتقدم که این احتمالا کم ارزش ترین گزینه است. الگوها را ترکیب کنید. این کار را زمانی انجام دهید که می‌خواهید موقعیت لنگر را به عنوان رویکرد اصلی خود، جفت شده با جاوا اسکریپت برای مرورگرهای پشتیبانی‌نشده، انجام دهید. یا یک پورتال برای قرار دادن DOM که با getBoundingClientRect() برای دقت مختصات جفت شده است.

نتیجه گیری من قبلاً با این اشکال به عنوان یک مشکل یکباره برخورد می کردم - چیزی برای اصلاح و حرکت از آن. اما زمانی که به اندازه کافی با آن نشستم تا بتوانم هر سه سیستم درگیر را درک کنم - بریده شدن سرریز، انباشتن زمینه ها و حاوی بلوک ها - احساس تصادفی بودن متوقف شد. می‌توانستم به یک فهرست شکسته نگاه کنم و فوراً ردیابی کنم که کدام جد مسئول است. این تغییر در نحوه خواندن من DOM نکته اصلی بود. هیچ پاسخ درست واحدی وجود ندارد. آنچه من به آن دست یافتم به آنچه می توانستم در پایگاه کد کنترل کنم بستگی داشت: پورتال هایی که درخت اجداد غیرقابل پیش بینی بود. موقعیت ثابت زمانی که تمیز و ساده بود. حرکت عنصر زمانی که هیچ چیز مانع من نشد. و موقعیت لنگر در حال حاضر،جایی که من می توانم هر چیزی که در نهایت انتخاب می کنید، دسترسی را به عنوان آخرین مرحله تلقی نکنید. در تجربه من، این دقیقا زمانی است که نادیده گرفته می شود. روابط ARIA، مدیریت فوکوس، رفتار صفحه‌کلید - اینها صیقل‌پذیر نیستند. آنها بخشی از چیزی هستند که باعث می شود چیز واقعاً کار کند. کد منبع کامل را در مخزن GitHub من بررسی کنید. ادامه مطلب اینها منابعی هستند که در حین کار بر روی این موضوع مدام به آنها باز می گشتم:

زمینه انباشتگی (MDN) "راهنمای موقعیت یابی لنگر CSS"، خوان دیگو رودریگز "شروع به کار با Popover API"، Godstime Aburu رابط کاربری شناور (floating-ui.com) سرریز 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