تودرتویی (Nesting) در CSS
درسهای قبل نام دادید به مقدار (--token) و با calc حسابش کردید. اینجا نوبت سلکتور است: استایل عنوان، دکمه و hover کارت را داخل همان .card بنویسید تا اسم والد را صد بار تکرار نکنید.
سلکتور فرزند را تو در تو بنویسید
یک rule را داخل rule دیگر بگذارید. اگر & نگذارید، سلکتور تو در تو معمولاً بهصورت فرزندِ نسلی (فاصله) به والد وصل میشود:
.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 — از & استفاده کنید:
.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 بومی معمولاً غلط یا بیمعنی است؛ & اتصال را روشن میکند.
ترکیبکنندهها با &
اگر فرزند مستقیم یا خواهر/برادر میخواهید، ترکیبکننده را بعد از & بگذارید — نه فقط فاصلهٔ نسلی:
.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 همانجا بماند که استایل کامپوننت است:
.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 {
--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 و حالت فشرده و توییک موبایل را یکجا نگه میدارد.
خودتان امتحان کنید
- قانونهای تخت
.card،.card .title،.card .metaرا زیر یک.cardتو در تو بازنویسی کنید. - روی
.linkبنویسید&:hoverتا فقط خود لینک رنگ عوض کند، نه یک span تو در تو. - داخل
.sidebarیک@media (min-width: 40rem)برای padding بگذارید؛ در DevTools سلکتور expandشده را ببینید. :hover { }بدون&را به&:hover { }درست کنید و ببینید validate میشود.- یک 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
🧠 دانش خود را بیازمایید
دانش خود را بیازمایید
خود را با این آزمون تعاملی به چالش بکشید و ببینید موضوع را چقدر خوب درک کردهاید
📝 دستورالعملها
- هر سوال را با دقت بخوانید
- بهترین پاسخ را برای هر سوال انتخاب کنید
- میتوانید آزمون را هر چند بار که میخواهید تکرار کنید
- پیشرفت شما در بالا نمایش داده میشود