حل با :has(): فاصله عمودی در متن طولانی

حل با :has(): فاصله عمودی در متن طولانی

اگر تا به حال روی سایت هایی با تعداد زیادی کار کرده اید متن طولانی - به خصوص سایت‌های CMS که در آن افراد می‌توانند متن‌هایی را در ویرایشگر WYSIWYG وارد کنند - احتمالاً مجبور شده‌اید CSS بنویسید تا فاصله عمودی بین عناصر مختلف تایپوگرافی مانند سرفصل‌ها، پاراگراف‌ها، فهرست‌ها و غیره را مدیریت کنید.

به‌طور شگفت‌انگیزی سخت است که به درستی این کار را انجام دهید. و این یکی از دلایلی است که چرا مواردی مانند پلاگین Tailwind Typography و Stack Overflow's Prose وجود دارد - اگرچه این موارد بسیار بیشتر از فاصله گذاری عمودی هستند.

فایرفاکس پشتیبانی می کند :has() پشت layout.css.has-selector.enabled پرچم in about:config در زمان نوشتن

چه چیزی فاصله عمودی تایپوگرافی را پیچیده می کند؟

مطمئناً باید به همین سادگی باشد که بگوییم هر عنصر - p, h2, ulو غیره - مقداری حاشیه بالا و/یا پایین دارد... درست است؟ متاسفانه اینطور نیست این رفتار مطلوب را در نظر بگیرید:

  • اولین و آخرین عنصر در یک بلوک متن طولانی نباید هیچ فضای اضافی در بالا یا پایین (به ترتیب) داشته باشند. این به این دلیل است که سایر عناصر غیر تایپوگرافیک هنوز به طور قابل پیش بینی در اطراف محتوای طولانی قرار می گیرند.
  • بخش‌های درون محتوای طولانی باید یک فضای بزرگ خوب بین خود داشته باشند. یک "بخش" یک عنوان است و تمام محتوای زیر که به آن عنوان تعلق دارد. در عمل، این به معنای داشتن یک فضای بزرگ خوب قبل از سرفصل است... اما نه اگر آن عنوان بلافاصله قبل از یک عنوان دیگر باشد!
مثالی از عنوان 3 پس از یک پاراگراف و دیگری پس از عنوان 2.
ما می خواهیم در بالای عنوان 3، زمانی که از یک عنصر تایپوگرافی پیروی می کند، مانند یک پاراگراف، فضای بیشتری داشته باشیم، اما زمانی که بلافاصله بعد از عنوان دیگری دنبال می شود، فضای کمتری داریم.

برای اینکه ببینید کجا می‌تواند مفید واقع شود، لازم نیست به اینجا در CSS-Tricks نگاه کنید. در اینجا چند اسکرین شات از فاصله گذاری که از مقاله دیگری برداشتم آمده است.

یک عنصر Heading 2 مستقیماً بالای عنوان 3.
فاصله عمودی بین عنوان 2 و عنوان 3
عنصر سرفصل 3 که مستقیماً از عنصر پاراگراف پیروی می کند.
فضای عمودی بین عنوان 3 و یک پاراگراف

راه حل سنتی

راه حل معمولی که من دیده ام شامل قرار دادن هر محتوای طولانی در یک بسته بندی است div (یا یک برچسب معنایی، در صورت لزوم). نام کلاس من این بوده است .rich-text، که فکر می‌کنم از نسخه‌های قدیمی‌تر Wagtail CMS استفاده می‌کنم، که این کلاس را به‌طور خودکار هنگام رندر کردن محتوای WYSIWYG اضافه می‌کند. تایپوگرافی باد دم با استفاده از .prose کلاس (به علاوه برخی از کلاس های اصلاح کننده).

سپس CSS را اضافه می کنیم تا تمام عناصر تایپوگرافی در آن wrapper انتخاب شود و حاشیه های عمودی اضافه شود. البته با توجه به رفتار خاصی که در بالا ذکر شد در مورد سرفصل های انباشته و عنصر اول/آخر.

راه حل سنتی معقول به نظر می رسد ... مشکل چیست؟ فکر کنم چندتا هست…

ساختار سفت و سخت

نیاز به اضافه کردن یک کلاس wrapper مانند .rich-text در همه مکان های مناسب به معنای پخت در یک ساختار خاص برای کد HTML شما است. این گاهی اوقات ضروری است، اما به نظر می رسد که نباید در این مورد خاص باشد. همچنین ممکن است به راحتی فراموش کنید که این کار را در هر جایی که نیاز دارید انجام دهید، به خصوص اگر نیاز به استفاده از آن برای ترکیبی از CMS و محتوای سخت کدگذاری شده دارید.

ساختار HTML زمانی سفت‌تر می‌شود که بتوانید حاشیه بالا و پایین را به ترتیب از اولین و آخرین عناصر برش دهید، زیرا آنها باید فرزندان فوری عنصر wrapper باشند، به عنوان مثال، .rich-text > *:first-child. این > مهم است - پس از همه، ما نمی خواهیم به طور تصادفی اولین مورد لیست را در هر کدام انتخاب کنیم ul or ol با این انتخابگر

ترکیب خواص حاشیه

در قبل:has() در دنیا، ما راهی برای انتخاب یک عنصر بر اساس آنچه به دنبال آن است، نداشته ایم. بنابراین، رویکرد سنتی برای فاصله‌گذاری عناصر تایپوگرافیک شامل استفاده از ترکیبی از هر دو است margin-top و margin-bottom:

  1. ما با تنظیم فاصله پیش‌فرض روی عناصر با شروع می‌کنیم margin-bottom.
  2. در مرحله بعد، با استفاده از «بخش‌های» خود فاصله می‌گذاریم margin-top - یعنی فضای بسیار بزرگ بالای هر عنوان
  3. سپس آن بزرگ ها را نادیده می گیریم margin-topهنگامی که یک عنوان بلافاصله با عنوان دیگری با استفاده از انتخابگر خواهر و برادر مجاور دنبال می شود (مثلاً h2 + h3).

حالا، شما را نمی‌دانم، اما همیشه احساس می‌کردم که بهتر است از یک جهت حاشیه استفاده کنید هنگام فاصله دادن چیزها، به طور کلی به نفع margin-bottom (با این فرض که CSS gap ویژگی امکان پذیر نیست، که در این مورد چنین نیست). این که آیا این موضوع مهمی است یا حتی درست است، به شما اجازه می‌دهم تصمیم بگیرید. اما شخصا ترجیح می دهم تنظیم کنم margin-bottom برای فاصله گذاری محتوای طولانی

حاشیه های در حال فروپاشی

به خاطر اینکه حاشیه های در حال فروپاشی، این ترکیب حاشیه های بالا و پایین فی نفسه مشکل بزرگی نیست. فقط بزرگتر از دو حاشیه انباشته اعمال می شود، نه مجموع هر دو حاشیه. اما... خوب... من واقعاً از فروپاشی حاشیه ها خوشم نمی آید.

فروپاشی حاشیه ها یک چیز دیگری است که باید از آن آگاه بود. ممکن است برای برنامه‌نویس‌های جوانی که با این ویژگی CSS سازگار نیستند، گیج‌کننده باشد. اگر بخواهید لفاف را به a تغییر دهید، فاصله کاملاً تغییر می کند (یعنی از بین رفتن متوقف می شود). flex طرح بندی با flex-direction: column به عنوان مثال، این چیزی است که اگر حاشیه های عمودی خود را در یک جهت تنظیم کنید، اتفاق نمی افتد.

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

La :has() راه حل

و در اینجا تلاش من برای حل این مسائل است :has().

برای جمع بندی بهبودهایی که این هدف ایجاد می کند:

  • هیچ کلاس لفافی مورد نیاز نیست.
  • ما در حال کار با a جهت حاشیه ثابت.
  • از فروپاشی حاشیه ها اجتناب می شود (که ممکن است بهبود باشد یا نباشد، بسته به موضع شما).
  • هیچ سبک تنظیمی وجود ندارد و بلافاصله آنها را نادیده می گیرند.

یادداشت ها و هشدارها در مورد :has() راه حل

  • همیشه پشتیبانی مرورگر را بررسی کنید. در زمان نوشتن ، فایرفاکس فقط پشتیبانی می کند :has() پشت پرچم آزمایشی.
  • راه حل من شامل تمام عناصر تایپوگرافی ممکن نیست. به عنوان مثال ، هیچ وجود دارد <blockquote> در نسخه ی نمایشی من فهرست انتخابگر به اندازه کافی برای گسترش آسان است.
  • راه حل من همچنین عناصر غیر تایپوگرافیک را کنترل نمی کند که ممکن است در بلوک‌های متن طولانی خاص شما وجود داشته باشد، به عنوان مثال <img>. دلیلش این است که برای سایت‌هایی که من روی آنها کار می‌کنم، ما تمایل داریم که WYSIWYG را تا آنجا که ممکن است برای گره‌های متن اصلی، مانند سرفصل‌ها، پاراگراف‌ها و فهرست‌ها قفل کنیم. هر چیز دیگری - به عنوان مثال نقل قول ها، تصاویر، جداول، و غیره - یک بلوک کامپوننت CMS جداگانه است، و خود آن بلوک ها هنگام ارائه در یک صفحه از یکدیگر فاصله دارند. اما باز هم لیست انتخابگر قابل تمدید است.
  • من فقط گنجانده ام h1 به خاطر کامل بودن من معمولاً به یک کاربر CMS اجازه اضافه کردن یک را نمی دهم h1 از طریق WYSIWYG، عنوان صفحه به جای وارد شدن در ویرایشگر صفحه CMS در جایی در قالب صفحه قرار می گیرد.
  • من برای عنوانی که بلافاصله پس از آن سرفصل همان سطح قرار می گیرد غذا نمی دهم (h2 + h2). این بدان معنی است که عنوان اول دارای هیچ محتوایی نیست، که به نظر سوء استفاده از سرفصل ها است (و اگر اشتباه می کنم، مرا تصحیح کنید، اما قدرت نقض WCAG 1.3.1 اطلاعات و روابط). همچنین سطوح سرفصل های نادیده گرفته شده را که نامعتبر هستند، تهیه نمی کنم.
  • من به هیچ وجه رویکردهای موجودی که ذکر کردم را زیر پا نمی گذارم. اگر و زمانی که من یک سایت Tailwind دیگر بسازم، از افزونه عالی Typography استفاده خواهم کرد، بدون شک!
  • من طراح نیستم من به این مقادیر فاصله با چشم انداختن آن رسیدم. احتمالاً می توانید (و باید) از مقادیر بهتری استفاده کنید.

ویژگی و ساختار پروژه

من قصد داشتم اینجا یک چیز بزرگ در مورد روش سنتی و روش جدید بنویسم :has() روش انجام آن ممکن است با آن مطابقت داشته باشد ITCSS روش شناسی... اما اکنون که داریم :where() (انتخابگر با ویژگی صفر) اکنون تقریباً می توانید سطح ویژگی دلخواه خود را برای هر انتخابگر انتخاب کنید.

گفتنی است، این واقعیت که ما دیگر با یک لفاف سروکار نداریم - .prose, .rich-textو غیره — به نظر من این احساس را ایجاد می کند که این باید در لایه "عناصر" زندگی کند، یعنی قبل از شروع به پرداختن به ویژگی های سطح کلاس. من استفاده کرده ام :where() در مثال های من برای ثابت نگه داشتن ویژگی. همه انتخابگرها در هر دو مثال من دارای یک هستند امتیاز ویژه of 0,0,1 (به جز تنظیم مجدد استخوان های برهنه).

پسگفتار

بنابراین شما آن را دارید، یک راه حل بی نظیر برای یک مشکل بسیار خسته کننده! این رویکرد جدیدتر هنوز آن چیزی نیست که من آن را CSS "ساده" می نامم - همانطور که در ابتدا گفتم، این موضوع پیچیده تر از آن چیزی است که در ابتدا به نظر می رسد. اما جدای از داشتن چند انتخابگر کمی پیچیده، من فکر می کنم رویکرد جدید به طور کلی منطقی تر است و ساختار HTML کمتر سفت و سخت بسیار جذاب به نظر می رسد.

اگر در نهایت از این یا چیزی شبیه به آن استفاده کردید، دوست دارم بدانم چگونه برای شما کار می کند. و اگر می توانید به راه هایی برای بهبود آن فکر کنید، من هم دوست دارم آنها را بشنوم!

تمبر زمان:

بیشتر از ترفندهای CSS