لایه های آبشاری به مرورگر شما می آیند

یونا کراوتس
یونا کراوتس

لایه‌های Cascade ( قانون CSS @layer ) به Chromium 99، Firefox 97 و Safari 15.4 Beta می‌آیند. آنها کنترل واضح تری بر فایل های CSS شما برای جلوگیری از تضادهای سبک خاص را امکان پذیر می کنند. این به ویژه برای پایگاه های کد بزرگ، سیستم های طراحی و هنگام مدیریت سبک های شخص ثالث در برنامه ها مفید است.

لایه بندی CSS خود به روشی واضح از تغییر سبک غیرمنتظره جلوگیری می کند و معماری بهتر CSS را ارتقا می دهد.

ویژگی CSS و آبشار

ویژگی CSS این است که چگونه CSS تصمیم می‌گیرد چه سبک‌هایی را برای کدام عناصر اعمال کند. انتخابگرهای مختلفی که می توانید استفاده کنید، ویژگی هر قانون سبک را تعیین می کند. به عنوان مثال، عناصر نسبت به کلاس ها یا ویژگی ها کمتر خاص هستند، که به نوبه خود کمتر از شناسه ها خاص هستند. این یک بخش اساسی از یادگیری CSS است.

مردم به قراردادهای نامگذاری CSS مانند BEM روی می آورند تا از نادیده گرفتن ویژگی های ناخواسته جلوگیری کنند. با دادن یک نام کلاسی به همه چیز، همه چیز در همان سطح مشخصه قرار می گیرد. با این حال، حفظ چنین سبک های سازمان یافته ای همیشه امکان پذیر نیست، به خصوص هنگام کار با کدهای شخص ثالث و سیستم های طراحی.

تصویری BEM از یک کارت با کلاس ها
یک مثال مصور از نامگذاری BEM از سایت keepinguptodate.com.

هدف لایه های آبشاری حل این مشکل است. آنها یک لایه جدید به آبشار CSS معرفی می کنند. در سبک های لایه ای، اولویت یک لایه همیشه بر ویژگی انتخابگر برتری دارد.

برای مثال، انتخابگر .post a.link دارای ویژگی بالاتری نسبت به .card a است. اگر بخواهید به یک پیوند، در داخل کارت، در یک پست استایل دهید، متوجه خواهید شد که انتخابگر خاص تری اعمال خواهد شد.

با استفاده از @layer ، می‌توانید در مورد ویژگی سبک هر کدام واضح‌تر باشید، و مطمئن شوید که سبک‌های پیوند کارت شما بر سبک‌های پیوند پست لغو می‌شوند، حتی اگر اگر تمام CSS شما در یک سطح باشد، ممکن است ویژگی از نظر عددی کمتر باشد. این به دلیل تقدم آبشاری است. سبک‌های لایه‌ای «هواپیما» آبشاری جدیدی ایجاد می‌کنند.

تصویر از نسخه ی نمایشی پروژه از شکستن UI

@layer در عمل

نسخه ی نمایشی رنگ پیوند با واردات را نشان می دهد
نسخه ی نمایشی را در Codepen ببینید.

این مثال قدرت لایه‌های آبشاری را با استفاده از @layer نشان می‌دهد. چندین پیوند نشان داده شده است: برخی از آنها بدون هیچ گونه نام کلاس اضافی اعمال شده، یکی با یک کلاس .link و دیگری با یک کلاس .pink . سپس CSS سه لایه اضافه می کند: base ، typography و utilities به شرح زیر:

@layer base {
  a {
    font-weight: 800;
    color: red; /* ignored */
  }

  .link {
    color: blue; /* ignored */
  }
}

@layer typography {
  a {
    color: green; /* styles *all* links */
  }
}

@layer utilities {
  .pink {
    color: hotpink;  /* styles *all* .pink's */
  }
}

در نهایت، همه پیوندها یا سبز یا صورتی هستند. این به این دلیل است که: در حالی که .link ویژگی سطح انتخابگر بالاتری نسبت به a دارد، یک سبک رنگ روی a در یک @layer با اولویت بالاتر وجود دارد. وقتی قانون سبز در یک لایه بعد از قانون آبی باشد a { color: green } .link { color: blue } را لغو می کند.

اولویت لایه بر ویژگی عنصر برتری دارد.

سازماندهی لایه ها

همانطور که در بالا نشان داده شده است می توانید لایه ها را مستقیماً در صفحه سازماندهی کنید یا می توانید آنها را در بالای یک فایل سازماندهی کنید.

ترتیب لایه ها با اولین باری که نام هر لایه در کد شما ظاهر می شود ایجاد می شود.

این بدان معناست که اگر موارد زیر را به بالای فایل اضافه کنید، پیوندها همه قرمز و پیوند با class .link آبی ظاهر می شوند:

@layer utilities, typography, base;

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

اسکرین شات پروژه Codepen
نسخه ی نمایشی را در Codepen ببینید.

ساماندهی واردات

راه دیگر برای استفاده از @layer با فایل های import است. شما می توانید این کار را مستقیماً هنگام وارد کردن استایل ها با استفاده از یک تابع layer() مانند مثال زیر انجام دهید.:

/* Base */
@import '../styles/base/normalize.css' layer(base); /* normalize or rest file */
@import '../styles/base/base.css' layer(base); /* body and base styles */
@import '../styles/base/theme.css' layer(theme); /* theme variables */
@import '../styles/base/typography.css' layer(theme); /* theme typography */
@import '../styles/base/utilities.css' layer(utilities); /* base utilities */

/* Layouts */
@import '../styles/components/post.css' layer(layouts); /* post layout */

/* Components */
@import '../styles/components/cards.css' layer(components); /* imports card */
@import '../styles/components/footer.css' layer(components); /* footer component */

قطعه کد بالا دارای سه لایه است: base ، layouts و components . نرمال سازی، تم، و فایل های تایپوگرافی در base ، با یک فایل post در layouts ، و cards و footer هر دو در components . هنگام وارد کردن فایل، لایه ها با استفاده از تابع لایه نمونه سازی می شوند. یک رویکرد جایگزین این است که لایه‌های خود را در بالای فایل سازماندهی کنید و آنها را قبل از هر وارد کردن اعلام کنید:

@layer base,
       theme,
       layouts,
       components,
       utilities;

اکنون، ترتیبی که در آن استایل‌های خود را @import ، برای ترتیب لایه‌ها اهمیتی ندارد، زیرا قبلاً در اولین نمونه از نام لایه ایجاد شده است. این یک چیز کمتر برای نگرانی است. همچنان می‌توانید فایل‌های وارد شده را روی لایه‌های خاصی تنظیم کنید، اما ترتیب از قبل تعیین شده است.

اسکرین شات از پروژه Codepen
پروژه را در Codepen کاوش کنید.

لایه ها و آبشار

بیایید یک قدم به عقب برگردیم و ببینیم که لایه‌ها در کجا استفاده می‌شوند، زیرا مربوط به آبشار گسترده‌تر است:

تصویر آبشار

ترتیب تقدم چنین است:

  • عامل کاربر عادی (کمترین اولویت)
  • کاربر محلی @layer
  • کاربر محلی عادی است
  • نویسنده @layers
  • نویسنده عادی
  • نویسنده !مهم
  • نویسنده @layer !important
  • کاربر محلی !مهم
  • عامل کاربر !important** (بالاترین اولویت)

ممکن است در اینجا متوجه شوید که استایل های @layer !important معکوس شده اند. به جای اینکه نسبت به سبک های غیر لایه (عادی) خاص باشند، اولویت بیشتری دارند. این به این دلیل است که !important چگونه در آبشار کار می‌کند: آبشار معمولی را در شیوه‌نامه‌های شما می‌شکند و ویژگی سطح لایه معمولی (اولویت) را معکوس می‌کند.

لایه های تو در تو

لایه ها را می توان در لایه های دیگر نیز تودرتو کرد. مثال زیر از توضیح دهنده لایه های Cascade از Miriam Suzanne آمده است:

@layer default {
  p { max-width: 70ch; }
}

@layer framework {
  @layer default {
    p { margin-block: 0.75em; }
  }

  p { margin-bottom: 1em; }
}

در قطعه کد بالا، می توانید با استفاده از یک framework.default دسترسی پیدا کنید . به عنوان نشانگر لایه default که در داخل framework تودرتو شده است. شما همچنین می توانید این را در قالب کوتاه تر بنویسید:

@layer framework.default {
  p { margin-block: 0.75em }
}

لایه های حاصل و ترتیب لایه ها عبارتند از:

  • پیش فرض
  • framework.default
  • framework بدون لایه
  • بدون لایه

چیزهایی که باید به آنها توجه کرد

لایه های آبشاری اگر به درستی از آنها استفاده کنید می توانند عالی باشند، اما همچنین می توانند سردرگمی اضافی و نتایج غیرمنتظره ای ایجاد کنند. هنگام کار با لایه های آبشاری به موارد زیر توجه کنید:

قانون 1: @layer برای محدوده استفاده نکنید

لایه های آبشاری محدوده را حل نمی کنند. اگر یک فایل CSS با @layer دارید، مثلا card.css و می‌خواهید به تمام پیوندهای داخل کارت استایل بدهید، سبک‌هایی مانند:

a {
  …
}

این منجر به این می شود که همه برچسب های a در فایل شما این لغو را دریافت کنند. هنوز هم مهم است که سبک های خود را به درستی در نظر بگیرید :

.card a {
  …
}

قانون 2: لایه های آبشاری پشت CSS بدون لایه مرتب می شوند

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

قانون 3: !important ویژگی آبشاری را معکوس می کند

در حالی که سبک های لایه ای کمتر از سبک های بدون لایه به طور کلی خاص هستند، استفاده از !important این امر را معکوس می کند. در یک لایه، اعلان‌هایی با قانون !important خاص‌تر از سبک‌های بدون لایه هستند.

در آن صورت، سبک های !important ویژگی خود را معکوس می کنند. نمودار بالا این را برای مرجع نشان می دهد: لایه های نویسنده @ دارای اولویت کمتری نسبت به نویسنده عادی هستند که اولویت کمتری نسبت به نویسنده !important دارند که اولویت کمتری نسبت به نویسنده @ لایه !important دارند.

اگر چندین لایه دارید، اولین لایه با !important اولویت !important را دارد و خاص ترین سبک است.

قانون 4: نقاط تزریق را درک کنید

از آنجایی که ترتیب لایه با اولین باری که نام هر لایه در کد شما ظاهر می شود ایجاد می شود، اگر یک اعلان @layer را پس از وارد کردن و تنظیم layer() ها یا بعد از یک دستور @layer مختلف قرار دهید، می توان آن را نادیده گرفت. برخلاف CSS، که در آن قاعده سبک در پایین‌ترین نقطه صفحه برای لایه‌های آبشاری اعمال می‌شود، نظم در مرحله اول برقرار می‌شود.

این می تواند در یک لیست، در یک بلوک لایه، یا در یک import باشد. اگر @layer بعد از یک لیست import با layer() قرار دهید، هیچ کاری انجام نمی دهد. قرار دادن آن در بالای فایل باعث می‌شود ترتیب لایه‌ها را تنظیم کند و به شما کمک کند لایه‌های داخل معماری را به وضوح ببینید.

قانون شماره 5: مراقب ویژگی خود باشید

با لایه‌های آبشاری، یک انتخاب‌گر با اختصاصی‌تر (مانند a ) یک انتخاب‌گر با خاص‌تر (مثل .link ) را لغو می‌کند، اگر آن انتخاب‌گر کم‌خاص روی یک لایه خاص‌تر باشد. موارد زیر را در نظر بگیرید:

a in layer(components) در layer(utilities) .pink را لغو می کند اگر: @layer utilities, components مشخص شده باشد. اگرچه بخشی عمدی از API است، اما اگر انتظارش را ندارید می‌تواند گیج‌کننده و خسته‌کننده باشد.

بنابراین، اگر در حال نوشتن کلاس‌های کاربردی هستید، همیشه آنها را به عنوان لایه‌ای با مرتبه بالاتر از مؤلفه‌هایی که قصد دارید آنها را لغو کنید، قرار دهید. ممکن است فکر کنید "من فقط این کلاس .pink را برای تغییر رنگ اضافه کردم و اعمال نمی شود".

درباره لایه های آبشاری بیشتر بدانید

همچنین می‌توانید این منابع را بررسی کنید تا درباره لایه‌های آبشاری بیشتر بدانید: