ساخت scrollspy فقط با CSS، بدون یه خط جاوااسکریپت
خلاصهٔ کاملتر
نویسنده تو این مقاله یه scrollspy میسازه، یعنی فهرست مطالبی (TOC) که وقتی صفحه رو اسکرول میکنی لینک بخشی که الان داری میخونی رو هایلایت میکنه. این الگو رو Bootstrap معروف کرد و معمولاً با جاوااسکریپت و ابزاری مثل IntersectionObserver پیاده میشه تا معلوم بشه کدوم بخش جلوی چشمه. حرف اصلی مقاله اینه که با چندتا قابلیت نسبتاً جدید CSS میشه همین کارو بدون جاوااسکریپت انجام داد. مارکآپ هم فقط یه لیست ol از لینکهاست که هر کدوم به یه بخش صفحه اشاره میکنه.
اولین قطعه، property جدید scroll-target-group هست که جزو CSS Overflow Module Level 5ئه؛ همون مشخصاتی که قابلیتهای carousel مثل ::scroll-marker رو آورد. وقتی روی یه عنصر scroll-target-group: auto بذاری، لینکهای داخلش که به یه fragment (یعنی آدرسهایی مثل #edge) اشاره میکنن میشن scroll marker و مرورگر هر لینک رو به بخش مقصدش وصل میکنه. بعد با pseudo-class :target-current لینک بخشی که الان دیده میشه رو استایل میدی:
.toc {
scroll-target-group: auto;
}
.toc a:target-current {
color: var(--color-accent);
}نویسنده تأکید میکنه scroll-target-group رو با scroll-marker-group قاطی نکنی؛ دومی خودش pseudo-elementهای ::scroll-marker رو میسازه، ولی اولی از همون لینکهایی که خودت نوشتی استفاده میکنه. غیر از :target-current، دوتا حالت :target-before و :target-after هم هست که به لینکهای قبل و بعد از لینک فعلی میخورن. نویسنده با ::before یه دایره کنار هر لینک گذاشته؛ دایرهٔ فعلی glow داره و دایرههای بعدی کوچیکتر و کمرنگترن. یعنی دیگه لازم نیست موقع اسکرول دستی کلاس اضافه یا حذف کنی.
برای اینکه دایرهها با یه خط پیوسته به هم وصل بشن، نویسنده سراغ anchor positioning رفته؛ یعنی قابلیتی که یه عنصر رو نسبت به یه عنصر دیگه (anchor) جاگذاری میکنه، بدون اینکه بدونی اون عنصر کجاست. خط یه ::before روی olئه که بالاش ثابته. لینک فعلی با anchor-name تبدیل به anchor میشه و پایین خط به مرکزش میچسبه:
.toc a:target-current {
anchor-name: --current-marker;
}
.toc ol::before {
position-anchor: --current-marker;
bottom: anchor(center);
}چون مقدار bottom با جابهجا شدن --current-marker عوض میشه، میشه بهش transition داد و یه حرکت نرم گرفت، حتی وقتی از بخش اول مستقیم میپری به آخر. این روش به تعداد آیتمها یا یکسان بودن ارتفاعشون هم وابسته نیست. البته نویسنده یه trade-off رو هم میگه: bottom یه property مربوط به layoutئه، پس مرورگر باید حین انیمیشن layout رو دوباره حساب کنه و نمیتونه مثل transform یا opacity کار رو بسپره به compositor (یعنی بخشی از مرورگر که انیمیشن رو جدا از چیدمان صفحه اجرا میکنه).
مهمترین محدودیت، پشتیبانی مرورگرهاست: این قابلیتها فعلاً فقط تو مرورگرهای مبتنی بر Chromium کار میکنن و Firefox و Safari هنوز پشتیبانیشون نمیکنن. ولی چون پایهٔ کار یه لیست ساده از لینکهاست، این مرورگرها هم یه ناوبری کاملاً قابلاستفاده دارن. به گفتهٔ نویسنده این یعنی progressive enhancement: HTML معمولی رو نگه میداری و هر جا مرورگر پشتیبانی کرد یه تجربهٔ بهتر بهش اضافه میکنی.
نکات کلیدی:
- scroll-target-group: auto لینکهای anchor داخل یه عنصر رو به scroll marker تبدیل میکنه.
- :target-current، :target-before و :target-after بهترتیب لینک فعلی، لینکهای قبلی و لینکهای بعدی رو هدف میگیرن.
- خط متحرک با anchor-name و bottom: anchor(center) به لینک فعلی وصل میشه.
- transition روی bottom باعث محاسبهٔ دوبارهٔ layout میشه و روی compositor اجرا نمیشه.
- فعلاً فقط مرورگرهای مبتنی بر Chromium پشتیبانی میکنن و Firefox و Safari هنوز نه.




