दिन 5: Advanced Selectors, Specificity और Cascade
✅ आज आप सीखेंगे
- Combinators: descendant, child, sibling
- Attribute selectors और :not(), :is(), :has()
- Pseudo-classes: :hover, :focus-visible, :nth-child, :checked
- Pseudo-elements: ::before, ::after, ::placeholder, ::marker
- Cascade, specificity, inheritance – “मेरी CSS काम नहीं करती” debug करना
🏢 असली दुनिया में
CSS developer को मिलने वाला सबसे आम message: “मैंने style.css में colour बदला पर कुछ नहीं हुआ।” दस में से नौ बार rule ठीक होता है – कोई दूसरा, ज़्यादा specific rule जीत जाता है। Specificity पढ़ना आ जाए तो ये bugs हर जगह !important लगाने की जगह 30 सेकंड में ठीक होते हैं।
Combinators
<style>
.menu a { color: #264de4; } /* descendant: any <a> inside .menu */
.menu > li { border-bottom: 1px solid #e5e7eb; } /* child: only direct <li> */
h3 + p { font-weight: 600; } /* adjacent sibling: the p right after h3 */
h3 ~ small { color: #9ca3af; } /* general sibling: any later small */
</style>
<ul class="menu">
<li><a href="#">Home</a></li>
<li><a href="#">Sweets</a>
<ul><li><a href="#">Dry sweets</a></li></ul>
</li>
</ul>
<h3>Kaju Katli</h3>
<p>This first paragraph is bold (h3 + p).</p>
<p>The second is normal.</p>
<small>Prices include GST (h3 ~ small)</small>Attribute selectors और logical pseudo-classes
<style>
a[href^="https"]::after { content: " ↗"; } /* starts with */
a[href$=".pdf"] { color: #b91c1c; } /* ends with */
a[href^="tel:"] { font-weight: 700; color: #15803d; }
input[type="email"] { border: 2px solid #264de4; }
li:not(:last-child) { margin-bottom: 6px; }
:is(h4, h5) span { color: #c2410c; }
.card:has(img) { border: 2px solid #f59e0b; padding: 6px; }
</style>
<p><a href="https://maps.google.com">Find us on Maps</a> · <a href="menu.pdf">Download menu</a> · <a href="tel:+919829012345">Call now</a></p>
<input type="email" placeholder="you@example.com">
<ul><li>One</li><li>Two</li><li>Three (no margin)</li></ul>
<h4>Today’s <span>special</span></h4>
<div class="card"><img src="images/ladoo-400.webp" alt="" width="80"> card with an image gets a gold border (:has)</div>Pseudo-classes: states और positions
<style>
.btn { background: #264de4; color: #fff; border: 0; padding: .6rem 1rem; border-radius: 8px; cursor: pointer; }
.btn:hover { background: #1e3a8a; }
.btn:active { transform: scale(.97); }
.btn:focus-visible { outline: 3px solid #f59e0b; outline-offset: 2px; }
.btn:disabled { background: #9ca3af; cursor: not-allowed; }
tr:nth-child(even) { background: #f1f5f9; }
tr:first-child { font-weight: 700; background: #264de4; color: #fff; }
input:checked + label { color: #15803d; font-weight: 700; text-decoration: line-through; }
</style>
<button class="btn">Hover / Tab to me</button> <button class="btn" disabled>Sold out</button>
<table style="margin-top:10px;border-collapse:collapse;width:100%">
<tr><td>Sweet</td><td>Price</td></tr><tr><td>Kaju katli</td><td>₹900</td></tr><tr><td>Ghewar</td><td>₹650</td></tr><tr><td>Ladoo</td><td>₹500</td></tr>
</table>
<p><input type="checkbox" id="t1"><label for="t1"> Pack 20 Diwali boxes</label></p>| Pseudo-class | किसे चुनता है |
|---|---|
| :hover / :active | Mouse ऊपर / दबाया जा रहा |
| :focus-visible ⭐ | Keyboard focus (outlines के लिए :focus से बेहतर) |
| :nth-child(2n) / (odd) / (3) | Siblings में स्थान |
| :first-child / :last-child | पहला / आख़िरी sibling |
| :checked, :disabled, :required, :invalid | Form states (Day 15) |
| :has(x) | x वाला parent – “parent selector” |
Pseudo-elements: ::before और ::after
<style>
.req::after { content: " *"; color: #dc2626; }
.new::before { content: "NEW"; background: #16a34a; color: #fff; font-size: 10px; font-weight: 700; padding: 2px 6px; border-radius: 4px; margin-right: 6px; }
.quote::before { content: "“"; font-size: 3rem; color: #f59e0b; line-height: 0; vertical-align: -0.4em; margin-right: 4px; }
ul.tick { list-style: none; padding: 0; }
ul.tick li::before { content: "✔"; color: #16a34a; margin-right: 8px; }
p::first-letter { font-size: 1.4em; font-weight: 700; color: #264de4; }
::selection { background: #fde68a; }
</style>
<p><label class="req">Mobile number</label></p>
<p class="new">Sugar-free kaju katli launched</p>
<p class="quote">Best ghewar in Jaipur!</p>
<ul class="tick"><li>Pure desi ghee</li><li>No preservatives</li><li>Made today</li></ul>::before/::after का text select नहीं होता और screen readers उसे अलग-अलग ढंग से पढ़ते हैं। ज़रूरी जानकारी (prices, निर्देश) वहाँ कभी न रखें।
Cascade: कौन जीतता है?
- 1Importance: !important सामान्य declarations को हराता है (इससे बचें)
- 2Specificity: ज़्यादा specific selector जीतता है
- 3Order: specificity बराबर हो तो जो rule बाद में लिखा, वह जीतता है
- 4Inheritance: कोई rule element को target न करे तो कुछ properties (color, font) parent से आती हैं
| Selector | Score (ID, class, element) | किसे हराता है |
|---|---|---|
| p | 0, 0, 1 | — |
| .price | 0, 1, 0 | कितने भी elements |
| .card .price | 0, 2, 0 | .price |
| nav ul li a:hover | 0, 1, 4 | .price? नहीं – 1 class = 1 class, फिर 4 elements 0 को हराते हैं |
| #special | 1, 0, 0 | कितनी भी classes |
| style="…" (inline) | सभी selectors को हराता है | सिर्फ़ !important इसे हराता है |
<style>
.card .price { color: #16a34a; } /* 0,2,0 – wins */
.price { color: #dc2626; } /* 0,1,0 – written later, but loses */
p { color: #374151; }
.card { color: #264de4; font-family: Georgia, serif; } /* inherited by children */
</style>
<div class="card">
<p>This text inherits the card’s font, but p sets its own colour.</p>
<span class="price">₹900 – green, because .card .price is more specific</span>
</div>असली debugging: “मेरा colour नहीं लगता”
- Element Inspect करें। क्या आपका rule दिखता भी है? नहीं तो: ग़लत selector, typo, या CSS file जुड़ी/cache नहीं (Ctrl+F5)।
- आपका rule कटा हुआ है? Styles pane में उसके ऊपर वाला rule देखें – वही जीत रहा है। Specificity मिलाएँ।
- मौजूदा pattern से मेल करके ठीक करें (जैसे .card .price लिखें), !important जोड़कर नहीं।
- अपनी CSS में flat, single-class selectors रखें (BEM, Day 17) ताकि ये लड़ाइयाँ शुरू ही न हों।
आज काम करता है, पर अगले fix को उसे हराने के लिए एक और !important चाहिए, और जल्द कुछ भी override नहीं होता। ठीक इस्तेमाल: .hidden { display: none !important } जैसी utility classes और ऐसी third-party CSS override करना जो आप बदल नहीं सकते।
🏅 आज के Job Skills
Practice tasks
🏋️ Practice – ख़ुद करें
Solution देखें
#nav .item a, ul li.active, .btn.primary:hover।Quick quiz
🧠 Quick Quiz – ख़ुद को जाँचें
Interview corner
💼 Interview Corner
Specificity कैसे गिनी जाती है?
Tuple (IDs, classes/attributes/pseudo-classes, elements/pseudo-elements) के रूप में, बाएँ से दाएँ तुलना। Inline styles selectors को हराते हैं; !important सामान्य declarations को; :where() शून्य जोड़ता है और :is()/:not() अपने सबसे specific argument की specificity लेते हैं।
Pseudo-class बनाम pseudo-element?
Pseudo-class (:hover) किसी ख़ास state या स्थान वाले element को चुनता है; pseudo-element (::before) element के किसी हिस्से को style करता है या ऐसा virtual child बनाता है जो HTML में नहीं है।
सारांश
- Combinators: space, >, +, ~; [href^="https"] जैसे attribute selectors।
- Pseudo-classes = states/स्थान; pseudo-elements = हिस्से/सजावट।
- Cascade क्रम: importance → specificity → source order → inheritance।
- DevTools में debug; !important और गहरे selectors से बचें।
Day 6: display, position (relative, absolute, fixed, sticky), z-index और overflow – badges, sticky headers और WhatsApp buttons।
