در حال بارگذاری...

تودرتویی (Nesting) در CSS

درس‌های قبل نام دادید به مقدار (--token) و با calc حسابش کردید. اینجا نوبت سلکتور است: استایل عنوان، دکمه و hover کارت را داخل همان .card بنویسید تا اسم والد را صد بار تکرار نکنید.

سلکتور فرزند را تو در تو بنویسید

یک rule را داخل rule دیگر بگذارید. اگر & نگذارید، سلکتور تو در تو معمولاً به‌صورت فرزندِ نسلی (فاصله) به والد وصل می‌شود:

Card styles nested under one parent

css
.card {
padding: 1.25rem;
border-radius: 0.75rem;
background: var(--surface, #fff);

.title {
margin: 0 0 0.5rem;
font-size: 1.25rem;
}

.body {
color: var(--muted, #444);
line-height: 1.5;
}
}

مرورگر این را به .card .title و .card .body باز می‌کند. مدل matching عوض نشده؛ nesting فقط چینش فایل را تمیزتر می‌کند.

& یعنی خودِ همان عنصر

وقتی باید روی همان عنصری که والد است استایل بزنید — :hover، :focus-visible، یا کلاس اضافه مثل .is-primary — از & استفاده کنید:

Hover and modifier on the same element

css
.button {
display: inline-flex;
padding: 0.6rem 1.1rem;
border: 0;
border-radius: 0.5rem;
background: var(--brand, #2563eb);
color: #fff;

&:hover {
background: var(--brand-hover, #1d4ed8);
}

&:focus-visible {
outline: 2px solid var(--brand, #2563eb);
outline-offset: 2px;
}

&.is-primary {
background: var(--brand-strong, #1e40af);
}
}

&:hover می‌شود .button:hover. &.is-primary می‌شود .button.is-primary. بدون &، یک :hover { } لخت در nesting بومی معمولاً غلط یا بی‌معنی است؛ & اتصال را روشن می‌کند.

ترکیب‌کننده‌ها با &

اگر فرزند مستقیم یا خواهر/برادر می‌خواهید، ترکیب‌کننده را بعد از & بگذارید — نه فقط فاصلهٔ نسلی:

Child and adjacent patterns with &

css
.nav {
display: flex;
gap: 0.75rem;

& > .item {
padding: 0.35rem 0.6rem;
}

& > .item + .item {
border-inline-start: 1px solid #ddd;
}

/* same as nesting .item without & — descendant */
.badge {
font-size: 0.75rem;
}
}

& > .item یعنی .nav > .item. .badge بدون & یعنی .nav .badge. عمدی انتخاب کنید؛ نسل‌های اتفاقی عمیق بوی بد nesting است.

@media را کنار همان کامپوننت بگذارید

at-ruleهایی مثل @media را می‌توانید داخل rule استایل بنویسید تا breakpoint همان‌جا بماند که استایل کامپوننت است:

Responsive tweaks beside the component

css
.hero {
padding: 2rem 1.25rem;

h1 {
font-size: clamp(1.75rem, 1.2rem + 2vw, 2.75rem);
}

@media (min-width: 48rem) {
padding: 3rem 2rem;

h1 {
max-width: 20ch;
}
}
}

بعد از expand، media همچنان روی .hero (و h1 داخلش) اعمال می‌شود. توکن و clamp از درس‌های قبل سر جایشان‌اند؛ nesting فقط جای rule را عوض می‌کند.

یک نگاه به الگوها

📊 میان‌بر nesting بومی

می‌نویسید معنایش کی به‌درد می‌خورد
.card { .title { } } .card .title استایل نسل زیر کامپوننت
.btn { &:hover { } } .btn:hover شبه‌کلاس روی همان عنصر
.btn { &.big { } } .btn.big کلاس اضافه روی همان عنصر
.nav { & > a { } } .nav > a فرزند مستقیم
.box { @media (…) { } } media محدود به سلکتور همان rule breakpoint کنار کامپوننت

تو در تو را کم‌عمق نگه دارید

دو سه سطح معمولاً خوانا می‌ماند. درخت پنج‌طبقه همان «هرم سلکتور» قدیمی Sass را زنده می‌کند: diff سخت، specificity بالا، استایلی که فقط داخل یک والد غول‌پیکر معنی دارد. یک ریشهٔ روشن (.card، .nav) بگیرید و حالت‌ها و فرزندان نزدیک را تو در تو کنید — نه کل صفحه را.

یک پنل واقعی: توکن + nest + حالت

این تکه سه ایدهٔ آخر toolkit را کنار هم می‌گذارد؛ تکرار درس calc یا variables نیست:

Panel with tokens, nested parts, and a state

css
.panel {
--panel-pad: 1rem;
padding: var(--panel-pad);
border: 1px solid #e5e7eb;
border-radius: 0.75rem;

.heading {
margin: 0 0 0.5rem;
font-weight: 600;
}

.actions {
display: flex;
gap: calc(var(--panel-pad) / 2);
margin-block-start: var(--panel-pad);
}

&.is-compact {
--panel-pad: 0.5rem;
}

@media (max-width: 36rem) {
.actions {
flex-direction: column;
}
}
}

توکن هنوز custom property است؛ calc هنوز فاصله می‌سازد؛ nesting فقط heading و actions و حالت فشرده و توییک موبایل را یک‌جا نگه می‌دارد.

خودتان امتحان کنید

  1. قانون‌های تخت .card، .card .title، .card .meta را زیر یک .card تو در تو بازنویسی کنید.
  2. روی .link بنویسید &:hover تا فقط خود لینک رنگ عوض کند، نه یک span تو در تو.
  3. داخل .sidebar یک @media (min-width: 40rem) برای padding بگذارید؛ در DevTools سلکتور expandشده را ببینید.
  4. :hover { } بدون & را به &:hover { } درست کنید و ببینید validate می‌شود.
  5. یک nest سه‌طبقهٔ شلوغ را با کلاس جدا برای بلوک داخلی به دو سطح برسانید.

اشتباه‌های رایج

  • :hover { } تو در تو بدون & — غلط یا خلاف منظورتان؛ &:hover بنویسید
  • فکر کردن که .child یعنی .parent.child — آن یکی &.child می‌خواهد
  • کپی کور &__element از عادت Sass — nesting بومی دستور زبان سلکتور CSS را دنبال می‌کند
  • پنج سطح تو در تو «چون می‌شود» — خوانایی و specificity آسیب می‌بینند
  • خیال اینکه nesting جای var() یا calc() را می‌گیرد — فقط سلکتور و at-rule را گروه می‌کند

جمع‌بندی

  • سلکتور فرزند را تو در تو بنویسید تا استایل کامپوننت محلی بماند؛ پیش‌فرض نسلی است
  • برای حالت همان عنصر (:hover، .is-active) و ترکیب‌کنندهٔ صریح از & استفاده کنید
  • @media را کنار همان کامپوننتی بگذارید که تنظیمش می‌کنید
  • nest را کم‌عمق نگه دارید؛ nesting ساختار است، نه توکن و نه ریاضی
  • قدم بعد Modern Toolkit: container queries — استایل از اندازهٔ والد، نه فقط viewport

🧠 دانش خود را بیازمایید

آماده شروع

دانش خود را بیازمایید

خود را با این آزمون تعاملی به چالش بکشید و ببینید موضوع را چقدر خوب درک کرده‌اید

❓
6
سوالات
🎯
70%
برای قبولی
♾️
∞
زمان
🔄
∞
تلاش‌ها

📝 دستورالعمل‌ها

  • هر سوال را با دقت بخوانید
  • بهترین پاسخ را برای هر سوال انتخاب کنید
  • می‌توانید آزمون را هر چند بار که می‌خواهید تکرار کنید
  • پیشرفت شما در بالا نمایش داده می‌شود