Topic 04 / 07

Modern CSS: Variables, Nesting & :has()

1. Simple Definition

Pehle CSS me Sass ya SCSS jaisa pre-processor lagana padta tha nesting aur variables ke liye. Aaj ka Modern CSS natively CSS Variables (Custom Properties), Native Nesting, aur web development ka sabse bada breakthrough — Parent Selector (:has()) support karta hai!

2. Real-Life Analogy

🎨 Global Theme Paint Bucket Aur Smart Spy Camera

CSS Variables: Ek central paint bucket jahan ek jagah color change kiya, aur ghar ke sabhi kamron ka color instant badal gaya (Dark mode switching).
Parent Selector (:has()): Deewar par laga smart spy camera — "Agar is room ke andar koi sofa rakha hai (:has(.sofa)), toh is deewar par wall-lamp jalayein!" (Pehle CSS me parent ko child ke aadhar par style karna impossible tha!).

3. Why Do We Need It?

Modern CSS features code ko 50% chota bana dete hain, Sass build tools ki requirement khatam kar dete hain, aur bina JavaScript ke dynamic interactive styling allow karte hain.

4. Syntax

/* 1. CSS Custom Properties (Variables) */
:root {
  --brand-color: #2563eb;
  --spacing-md: 1.5rem;
}

.btn {
  background-color: var(--brand-color);
  padding: var(--spacing-md);
}

/* 2. Native CSS Nesting (Like Sass, but 100% native!) */
.card {
  background: white;
  padding: 1rem;

  & h2 { color: #0f172a; }
  & p  { color: #64748b; }

  &:hover {
    transform: translateY(-4px);
  }
}

/* 3. The Incredible :has() Selector */
/* Card jiske andar image hai use alag style karo */
.card:has(img) {
  padding-top: 0;
}

5. Basic Example (Theme Switcher using CSS Variables)

<div class="theme-box">
  <h3>Dynamic Variable Theme</h3>
  <p>Ye box CSS variable ke single switch se live re-theme hota hai.</p>
</div>

<style>
  :root {
    --theme-bg: #0f172a;
    --theme-text: #38bdf8;
  }
  .theme-box {
    background: var(--theme-bg);
    color: var(--theme-text);
    padding: 1.5rem;
    border-radius: 8px;
  }
</style>

6. Output / Expected Result

Dynamic Variable Theme Demo

--theme-bg aur --theme-text tokens ke sath render ho raha hai.

7. Code Explanation

  • --variable-name: Hamesha double dash -- se shuru hota hai.
  • var(--name, fallback): Variable ki value read karta hai, aur agar variable na mile toh fallback value use karta hai.
  • & (Ampersand in Nesting): Current parent selector ko represent karta hai (e.g. &:hover).
  • :has(): Parent ko target karta hai based on condition of child or state (e.g. form:has(:invalid) button { opacity: 0.5; }).

8. Real-World Example

Modern Dark/Light mode implementations (jaise is website par) [data-theme="dark"] attribute ke andar CSS variables swap karke instantly execute hoti hain bina kisi page refresh ke.

9. Common Mistakes

⚠️ Galti: CSS variable ko JavaScript me galat access karna

JS me variable read karne ke liye getComputedStyle(element).getPropertyValue('--primary-color') use hota hai, direct element.style.--color nahi!

10. Best Practices

  • Global design tokens (colors, radii, shadows) ko hamesha :root { ... } me define karein.
  • Deep nesting (3 levels se zyada) mat karein taaki CSS readability kharab na ho.

11. Try It Yourself

Playground me --card-color: purple; variable banakar card par var(--card-color) apply karein.

12. Challenge

:has() use karke ek form banayein jisme agar koi input :invalid ho, toh pure form ka border red highlight ho jaye bina JavaScript ke!

13. Interview Questions

💼 Q: CSS Variables (Custom Properties) aur Sass variables me sabse bada technical difference kya hai?

Answer:
1. Sass Variables: Build-time par compile hokar static values ban jaate hain. Browser ko unka pata nahi hota aur wo DOM aware nahi hote.
2. CSS Variables: Runtime live DOM objects hote hain. Inhe JavaScript se dynamically update kiya ja sakta hai aur ye cascade/inheritance follow karte hain!

14. Quick Revision

  • --name: value; & var(--name).
  • Native Nesting = Zero build tools needed.
  • :has() = The Parent Selector.

15. FAQ

Q1. calc() function me space kyun zaroori hai?

calc(100% - 20px) me minus sign ke dono taraf space compulsory hai, warna browser ise negative number (-20px) samajh kar syntax error de deta hai.

Q2. CSS Variables case-sensitive hote hain?

Haan! --main-color aur --Main-Color do alag variables maane jaate hain.

Q3. :is() aur :where() me kya fark hai?

:is() apne andar ke sabse highest selector ki specificity leta hai; :where() hamesha 0 specificity deta hai (easy overrides ke liye best!).

Q4. Kya sabhi modern browsers me :has() supported hai?

Haan! :has() Chrome, Safari, Firefox aur Edge sabhi me modern Baseline supported hai.

Q5. @supports query kya karti hai?

Feature queries browser me check karti hain ki koi modern CSS property supported hai ya nahi (e.g. @supports (display: grid) { ... }).

Topic 04 / 07

Modern CSS: Variables, Nesting & :has()

1. Simple Definition

Modern CSS encompasses next-generation capabilities that have eliminated the need for build-step preprocessors (like Sass). These include native CSS Custom Properties (Variables), native CSS Nesting, the transformative parent selector :has(), and color-mix().

2. Real-Life Analogy

🎛️ Master Control Switchboard

Imagine a modern smart hotel where changing the ambient lighting from "Daylight" to "Sunset Mood" requires flicking a single master knob (a CSS Variable) rather than repainting every lightbulb individually in each suite!

3. CSS Custom Properties (Variables)

/* Declaring variables at the root level */
:root {
  --brand-primary: #2563eb;
  --bg-surface: #ffffff;
  --text-main: #0f172a;
  --radius-md: 8px;
}

/* Instant dark theme override */
[data-theme="dark"] {
  --bg-surface: #0f172a;
  --text-main: #f8fafc;
}

/* Consuming variables */
.card {
  background: var(--bg-surface);
  color: var(--text-main);
  border-radius: var(--radius-md);
}

4. Native CSS Nesting (Zero Build Tools Needed)

/* Clean, readable nested CSS supported natively in all modern browsers */
.article-card {
  background: var(--bg-surface);
  padding: 1.5rem;

  /* Nested heading */
  h2 {
    color: var(--brand-primary);
  }

  /* Direct parent reference with & */
  &:hover {
    transform: translateY(-4px);
  }

  /* Nested child element */
  .read-more {
    font-weight: 600;
  }
}

5. The Mighty :has() Relational Selector

/* Target the parent card ONLY if it contains an image */
.card:has(img) {
  grid-template-rows: 200px 1fr;
}

/* Target a form when an input inside is invalid */
form:has(input:invalid) button[type="submit"] {
  opacity: 0.6;
  pointer-events: none;
}

6. Common Mistakes

⚠️ Common Pitfall: Over-Nesting

Just because CSS supports native nesting does not mean you should nest 6 levels deep! Nesting deeper than 3 levels produces excessive specificity and bloated styling hierarchies. Keep it flat and intentional.

7. Best Practices

  • Define global design tokens (colors, spacing, radii) inside :root.
  • Leverage :has() to eliminate unnecessary JavaScript DOM manipulation for UI states.
  • Provide sensible fallback values in var(--custom-prop, fallbackValue).

8. Practice Exercise

🎯 Exercise: Dark/Light Mode Theme Switcher

Build a profile card styled completely with CSS Custom Properties. Add a small JavaScript toggle that swaps the data-theme="dark" attribute on the <html> element!

9. Interview Questions

💼 Q: Why is :has() called the "CSS Parent Selector"?

Answer: Historically, CSS could only select downwards into children or sideways to siblings. :has() enables conditional styling of an ancestor or parent element based on what children or states it currently contains.

10. Summary / Cheat Card

  • CSS Variables: --var-name: value; and var(--var-name).
  • Native nesting with & is supported across 100% of modern browsers.
  • :has() styles parent elements based on child conditions.

11. FAQ

Q1. Can CSS variables be updated via JavaScript?

Yes! Via document.documentElement.style.setProperty('--brand-primary', '#10b981');.

Q2. Do CSS variables inherit through the DOM tree?

Yes! CSS Custom Properties cascade and inherit naturally just like standard CSS properties.