CSS Nesting

یکی از ویژگی‌های مورد علاقه پیش‌پردازنده CSS اکنون در این زبان گنجانده شده است: قوانین سبک تودرتو.

آدام آرگیل
Adam Argyle

قبل از تودرتو، هر انتخابگر باید به صراحت، جدا از یکدیگر اعلام شود. این منجر به تکرار، حجیم شدن شیوه نامه و تجربه نگارش پراکنده می شود.

قبل از
.nesting {
  color: hotpink;
}

.nesting > .is {
  color: rebeccapurple;
}

.nesting > .is > .awesome {
  color: deeppink;
}

پس از تودرتو ، انتخابگرها را می توان ادامه داد و قوانین سبک مربوط به آن را می توان در آن گروه بندی کرد.

بعد از
.nesting {
  color: hotpink;

  > .is {
    color: rebeccapurple;

    > .awesome {
      color: deeppink;
    }
  }
}

این را در مرورگر امتحان کنید .

Nesting با کاهش نیاز به تکرار انتخابگرها و همچنین قرار دادن قوانین سبک برای عناصر مرتبط به توسعه دهندگان کمک می کند. همچنین می تواند به سبک ها کمک کند تا با HTML مورد نظر مطابقت داشته باشند. اگر جزء .nesting در مثال قبلی از پروژه حذف شد، می‌توانید به جای جستجوی فایل‌ها برای نمونه‌های انتخابگر مرتبط، کل گروه را حذف کنید.

Nesting می تواند در موارد زیر کمک کند: - سازماندهی - کاهش اندازه فایل - Refactoring

Nesting از Chrome 112 در دسترس است و همچنین برای امتحان در Safari Technical Preview 162 در دسترس است.

شروع کار با CSS Nesting

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

شبکه ای رنگارنگ از دایره های کوچک و بزرگ، مثلث ها و مربع ها.

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

<div class="demo">
  <div class="sm triangle pink"></div>
  <div class="sm triangle blue"></div>
  <div class="square blue"></div>
  <div class="sm square pink"></div>
  <div class="sm square blue"></div>
  <div class="circle pink"></div>
  …
</div>

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

تودرتوی CSS به شما اجازه می دهد تا برای یک عنصر در متن انتخابگر دیگری استایل تعریف کنید.

.parent {
  color: blue;

  .child {
    color: red;
  }
}

در این مثال، انتخابگر کلاس .child در انتخابگر کلاس .parent قرار دارد. این بدان معناست که انتخابگر .child تودرتو فقط برای عناصری اعمال می شود که فرزندان عناصر با کلاس .parent هستند.

این مثال می‌تواند با استفاده از نماد & نوشته شود تا مشخصاً محل قرارگیری کلاس والد را مشخص کند.

.parent {
  color: blue;

  & .child {
    color: red;
  }
}

این دو مثال از نظر عملکردی معادل هستند و با بررسی مثال‌های پیشرفته‌تر در این مقاله، دلیل وجود گزینه‌ها واضح‌تر می‌شود.

انتخاب دایره ها

برای مثال اول، وظیفه اضافه کردن سبک‌ها برای محو و محو کردن دایره‌های داخل دمو است.

بدون تودرتو ، CSS امروز:

.demo .circle {
  opacity: .25;
  filter: blur(25px);
}

با تودرتو ، دو راه معتبر وجود دارد:

/* & is explicitly placed in front of .circle */
.demo {
  & .circle {
    opacity: .25;
    filter: blur(25px);
  }
}

یا

/* & + " " space is added for you */
.demo {
  .circle {
    opacity: .25;
    filter: blur(25px);
  }
}

در نتیجه ، تمام عناصر داخل .demo با کلاس .circle محو شده و تقریباً نامرئی می‌شوند:

شبکه رنگارنگ اشکال دیگر دایره ندارد، آنها در پس زمینه بسیار کم رنگ هستند.
نسخه ی نمایشی را امتحان کنید

انتخاب هر مثلث و مربع

این کار مستلزم انتخاب چندین عنصر تو در تو است که انتخابگر گروه نیز نامیده می شود.

بدون تودرتو ، CSS امروزه، دو راه وجود دارد:

.demo .triangle,
.demo .square {
  opacity: .25;
  filter: blur(25px);
}

یا با استفاده از :is()

/* grouped with :is() */
.demo :is(.triangle, .square) {
  opacity: .25;
  filter: blur(25px);
}

با تودرتو ، در اینجا دو راه معتبر وجود دارد:

.demo {
  & .triangle,
  & .square {
    opacity: .25;
    filter: blur(25px);
  }
}

یا

.demo {
  .triangle, .square {
    opacity: .25;
    filter: blur(25px);
  }
}

در نتیجه فقط عناصر .circle در داخل .demo باقی می مانند:

شبکه رنگارنگ اشکال تنها با دایره ها باقی مانده است، همه اشکال دیگر تقریباً نامرئی هستند.
نسخه ی نمایشی را امتحان کنید

انتخاب مثلث ها و دایره های بزرگ

این کار به یک انتخابگر ترکیبی نیاز دارد که در آن عناصر باید هر دو کلاس را داشته باشند تا انتخاب شوند.

بدون تودرتو ، CSS امروز:

.demo .lg.triangle,
.demo .lg.square {
  opacity: .25;
  filter: blur(25px);
}

یا

.demo .lg:is(.triangle, .circle) {
  opacity: .25;
  filter: blur(25px);
}

با تودرتو ، در اینجا دو راه معتبر وجود دارد:

.demo {
  .lg.triangle,
  .lg.circle {
    opacity: .25;
    filter: blur(25px);
  }
}

یا

.demo {
  .lg {
    &.triangle,
    &.circle {
      opacity: .25;
      filter: blur(25px);
    }
  }
}

در نتیجه ، تمام مثلث ها و دایره های بزرگ در داخل .demo پنهان می شوند:

شبکه رنگارنگ فقط دارای اشکال کوچک و متوسط ​​قابل مشاهده است.
نسخه ی نمایشی را امتحان کنید
نوک حرفه ای با انتخابگرهای ترکیبی و تودرتو

نماد & در اینجا دوست شماست زیرا به صراحت نحوه اتصال انتخابگرهای تو در تو را نشان می دهد. به مثال زیر توجه کنید:

.demo {
  .lg {
    .triangle,
    .circle {
      opacity: .25;
      filter: blur(25px);
    }
  }
}

اگرچه یک روش معتبر برای لانه سازی است، اما نتایج با عناصری که ممکن است انتظار دارید مطابقت نداشته باشد. دلیل آن این است که بدون & برای مشخص کردن نتیجه دلخواه .lg.triangle, .lg.circle با هم ترکیب شده اند، نتیجه واقعی .lg .triangle, .lg .circle خواهد بود. منتخب نوادگان .

انتخاب همه اشکال به جز صورتی

این کار به یک کلاس شبه تابعی نفی نیاز دارد که در آن عناصر نباید انتخابگر مشخص شده را داشته باشند.

بدون تودرتو ، CSS امروز:

.demo :not(.pink) {
  opacity: .25;
  filter: blur(25px);
}

با تودرتو ، در اینجا دو راه معتبر وجود دارد:

.demo {
  :not(.pink) {
    opacity: .25;
    filter: blur(25px);
  }
}

یا

.demo {
  & :not(.pink) {
    opacity: .25;
    filter: blur(25px);
  }
}

در نتیجه ، تمام اشکالی که صورتی نیستند در داخل .demo پنهان می شوند:

شبکه رنگارنگ اکنون تک رنگ است و فقط اشکال صورتی را نشان می دهد.
نسخه ی نمایشی را امتحان کنید
دقت و انعطاف پذیری با &

فرض کنید می‌خواهید .demo با انتخابگر :not() هدف قرار دهید. & برای آن لازم است :

.demo {
  &:not() {
    ...
  }
}

این .demo و :not() را به .demo:not() ترکیب می کند، برخلاف مثال قبلی که نیاز به .demo :not() داشت. این یادآوری زمانی که می خواهید یک تعامل :hover لانه کنید بسیار مهم می شود.

.demo {
  &:hover {
    /* .demo:hover */
  }

  :hover {
    /* .demo :hover */
  }
}

نمونه های بیشتر تودرتو

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

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

تودرتوی @media

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

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

.card {
  font-size: 1rem;

  @media (width >= 1024px) {
    font-size: 1.25rem;
  }
}

استفاده از & صریح نیز می تواند مورد استفاده قرار گیرد:

.card {
  font-size: 1rem;

  @media (width >= 1024px) {
    &.large {
      font-size: 1.25rem;
    }
  }
}

این مثال نحو گسترش‌یافته با & را نشان می‌دهد، در حالی که کارت‌های .large را نیز هدف قرار می‌دهد تا ویژگی‌های تودرتوی اضافی را به کار خود نشان دهد.

درباره nesting @rules بیشتر بیاموزید.

لانه سازی در هر جایی

تمام مثال‌ها تا این مرحله ادامه یافته یا به زمینه قبلی اضافه شده‌اند. در صورت نیاز می توانید زمینه را به طور کامل تغییر دهید یا دوباره مرتب کنید.

.card {
  .featured & {
    /* .featured .card */
  }
}

نماد & نشان دهنده ارجاع به یک شی انتخابگر (نه رشته) است و می تواند در هر جایی از انتخابگر تودرتو قرار گیرد. حتی می توان آن را چندین بار قرار داد:

.card {
  .featured & & & {
    /* .featured .card .card .card */
  }
}

در حالی که این مثال کمی بی فایده به نظر می رسد، مطمئناً سناریوهایی وجود دارد که در آن امکان تکرار یک زمینه انتخابگر مفید است.

نمونه های تودرتو نامعتبر

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

تودرتو و الحاق

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

.card {
  &--header {
    /* is not equal to ".card--header" */
  }
}

توضیح عمیق تر را می توان در مشخصات یافت.

نمونه تودرتو روی حیله و تزویر

تودرتو در لیست های انتخابگر و :is()

بلوک CSS تودرتو زیر را در نظر بگیرید:

.one, #two {
  .three {
    /* some styles */
  }
}

این اولین مثالی است که با یک لیست انتخابگر شروع می شود و سپس به لانه سازی ادامه می دهد. نمونه های قبلی فقط با یک لیست انتخابگر خاتمه می یافتند. هیچ چیز نامعتبر در این مثال تودرتو وجود ندارد، اما جزئیات پیاده سازی بالقوه پیچیده ای در مورد تودرتو در لیست های انتخابگر وجود دارد، به خصوص آنهایی که شامل یک انتخابگر ID هستند.

برای اینکه هدف تودرتو کار کند، هر فهرست انتخابی که درونی ترین تودرتو نیست، توسط مرورگر با :is() پیچیده می شود. این بسته بندی گروه بندی لیست انتخابگر را در هر زمینه های نوشته شده حفظ می کند. اثر جانبی این گروه بندی، :is(.one, #two) ، این است که ویژگی بالاترین امتیاز را در انتخابگرهای داخل پرانتز اتخاذ می کند. :is() همیشه کار می کند ، اما ممکن است هنگام استفاده از نحو تودرتو تعجب آور باشد زیرا دقیقاً آن چیزی نیست که نوشته شده است. ترفند به طور خلاصه؛ تودرتو با شناسه‌ها و فهرست‌های انتخابگر می‌تواند به انتخابگرهایی با ویژگی بسیار بالا منجر شود.

برای خلاصه کردن واضح مثال پیچیده، بلوک تودرتو قبلی به صورت زیر به سند اعمال می شود:

:is(.one, #two) .three {
  /* some styles */
}

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

اختلاط لانه سازی و اعلامیه ها

بلوک CSS تودرتو زیر را در نظر بگیرید:

.card {
  color: green;
  & { color: blue; }
  color: red;
}

رنگ عناصر .card blue خواهد بود.

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

راه هایی در اطراف آن وجود دارد. موارد زیر سه سبک رنگ را در & می‌پیچد که نظم آبشاری را همانطور که نویسنده قصد داشته است حفظ می‌کند. رنگ عناصر .card قرمز خواهد بود.

.card {
  color: green;
  & { color: blue; }
  & { color: red; }
}

در واقع، تمرین خوبی است که هر سبکی را که به دنبال تودرتو می‌آید با یک & بپیچید.

.card {
  color: green;

  @media (prefers-color-scheme: dark) {
    color: lightgreen;
  }

  & {
    aspect-ratio: 4/3;
  }
}

تشخیص ویژگی

دو راه عالی برای شناسایی ویژگی‌های تودرتوی CSS وجود دارد: از nesting استفاده کنید یا از @supports برای بررسی قابلیت تجزیه انتخابگر تودرتو استفاده کنید.

یک اسکرین شات از نسخه ی نمایشی Codepen Bramus که از شما می پرسد آیا مرورگر شما از CSS تودرتو پشتیبانی می کند یا خیر. در زیر این سوال یک جعبه سبز وجود دارد که از پشتیبانی سیگنال می‌دهد.

استفاده از تودرتو:

html {
  .has-nesting {
    display: block;
  }

  .no-nesting {
    display: none;
  }
}

استفاده از @supports :

@supports (selector(&)) {
  /* nesting parsing available */
}

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

اشکال زدایی با کروم DevTools

پشتیبانی فعلی در DevTools برای تودرتو حداقل است. در حال حاضر می‌بینید که سبک‌ها همانطور که انتظار می‌رود در قسمت Styles نشان داده شده‌اند، اما ردیابی تودرتو و زمینه انتخابگر کامل آن هنوز پشتیبانی نمی‌شود. ما طراحی و برنامه‌هایی برای شفاف و روشن کردن این موضوع داریم.

تصویری از نحو تودرتوی ابزارهای توسعه دهنده Chrome.

Chrome 113 قصد دارد از CSS Nesting پشتیبانی بیشتری داشته باشد. با ما همراه باشید.

آینده

CSS Nesting فقط در نسخه 1 است. نسخه 2 قندهای نحوی بیشتری را معرفی می کند و قواعد بالقوه کمتری را برای حفظ کردن معرفی می کند. تقاضای زیادی برای تجزیه تودرتو وجود دارد که محدود نباشد یا لحظات دشواری داشته باشد.

Nesting یک پیشرفت بزرگ برای زبان CSS است. تقریباً در تمام جنبه های معماری CSS مفاهیم تألیفی دارد. این تأثیر بزرگ باید قبل از اینکه نسخه 2 به طور مؤثر مشخص شود، عمیقاً بررسی و درک شود.

به عنوان آخرین فکر، در اینجا یک نسخه نمایشی است که از @scope ، nesting و @layer همه با هم استفاده می‌کند. این همه بسیار هیجان انگیز است!

یک کارت روشن در زمینه خاکستری. این کارت دارای عنوان و متن، چند دکمه اکشن و تصویری به سبک پانک سایبری است.