diff --git a/docs/css/basics/cascading-order.mdx b/docs/css/basics/cascading-order.mdx index 85d3902..f488562 100644 --- a/docs/css/basics/cascading-order.mdx +++ b/docs/css/basics/cascading-order.mdx @@ -5,95 +5,147 @@ description: "Understand the three core principles (C-S-I) that determine which keywords: [CSS Cascade, CSS Specificity, CSS Inheritance, Rule Conflict, Important rule, important, CodeHarborHub CSS] --- -You now know three different places to put your CSS: **Inline**, **Internal**, and **External**. But what happens when you set an element's color to blue in an external file and then try to set it to red using an internal style? +You now know there are three ways to write CSS: Inline, Internal, and External. But what happens when you accidentally apply **two different styles** to the same element? -The browser uses three fundamental principles, often called the **C-S-I** (Cascade, Specificity, Inheritance), to decide which rule wins and is actually applied. This is the **most crucial concept** in CSS. +The browser doesn't guess; it uses a strict set of rules known as the **Cascade** to determine which style wins. The Cascade is the process that combines three core concepts to resolve conflicts and apply the final styles: -## 1. The Cascade: Where Does the Style Come From? +1. **The Cascade:** Where does the style come from? +2. **Specificity:** How detailed is the selector? +3. **Inheritance:** Does the element automatically get its parent's style? -The **Cascade** determines the order in which CSS rules are processed and how conflicts are resolved based on the **source and order** of the styles. +## 1. The Cascade: Order and Source -In a conflict, the browser looks at the following sources, in order of increasing importance: +The **Cascade** is the primary system for layering styles. It decides the initial winner based on the origin and order of the stylesheet. -### A. Origin and Importance (The !important Rule) +### Source Order (The "Where" of the Style) -| Order | Source | Description | +Styles are prioritized based on their source. Think of it as a river flowing downhill—styles closer to the element tend to flow last and have more power: + +| Priority | Source | Description | | :--- | :--- | :--- | -| **1 (Lowest)** | Browser Defaults | The default styling applied by the browser (e.g., links are blue and underlined). | -| **2** | User Stylesheets | Styles set by the user (rare, used for accessibility purposes). | -| **3** | Author Stylesheets | **Your code** (External, Internal, and most Inline styles). | -| **4 (Highest)** | `!important` | Any rule followed by `!important` overrides almost everything else. **Avoid using this** unless absolutely necessary, as it breaks the natural flow of the cascade. | +| **Highest** | **User Styles** (High Specificity) | Styles applied directly by the user (e.g., accessibility settings). | +| **2nd Highest** | **Author's Styles** (`!important`) | Any rule in your CSS file marked with `!important`. | +| **3rd Highest** | **Author's Styles** (Normal) | **Your External, Internal, and Inline styles** (where Specificity rules the day). | +| **Lowest** | **Browser Default Styles** | Default styles set by the browser (e.g., blue links, large `

`). | -### B. Order of Appearance +### **The Role of Order:** -If two rules have the exact same **Origin** (e.g., both are in your external file) and the same **Specificity** (covered next), the rule that appears **later** in the stylesheet or the HTML document **wins**. +If two rules have the exact same Specificity (we'll cover this next) and come from the same source (e.g., two rules in your external stylesheet), the **last rule defined wins**. ```css title="styles.css" -/* Rule 1 appears first */ -p { color: red; } - -/* Rule 2 appears later and has the same specificity, so it wins */ -p { color: blue; } -/* The paragraph will be blue. */ -```` +p { color: blue; } /* This rule is defined first. */ +p { color: red; } /* This rule is defined last, so all

text will be RED. */ +``` ## 2. Specificity: Who is More Precise? -When multiple rules target the same element, **Specificity** is the unique score assigned to a CSS selector that determines which rule is applied. The selector with the **higher score always wins**, regardless of the order it appears in the stylesheet. +When two or more selectors try to style the same element, the browser calculates which selector is **more specific**. The selector with the highest specificity score always wins, regardless of where it appears in the CSS file (unless it's overridden by `!important`). -### Specificity Scoring +Specificity is calculated by counting different types of selectors. Think of it as a four-digit number $(A, B, C, D)$, where the highest number in the most significant column wins. -Specificity is calculated using a four-digit number, often written as `(A, B, C, D)`. +### Specificity Score Breakdown -| Category | Score | Example | Notes | +| Letter | Selector Type | Example | Value | | :--- | :--- | :--- | :--- | -| **A: Inline** | 1000 | `

` | Always wins over non-inline styles. | -| **B: IDs** | 100 | `#main-header` | A unique identifier. | -| **C: Classes, Attributes, Pseudo-classes** | 10 | `.card`, `[type="text"]`, `:hover` | Includes most common selectors. | -| **D: Elements, Pseudo-elements** | 1 | `p`, `h1`, `::before` | The lowest score. | +| **A** | **Inline Styles** | `

` | **1000** | +| **B** | **IDs** | `#main-nav` | **100** | +| **C** | **Classes, Attributes, Pseudo-classes** | `.card`, `[type="text"]`, `:hover` | **10** | +| **D** | **Elements and Pseudo-elements** | `p`, `div`, `::after` | **1** | ### Specificity Example -Let's look at a common conflict: +Let's compare two conflicting selectors: -| Selector | Calculation | Specificity Score | -| :--- | :--- | :--- | -| `h1` | (0, 0, 0, 1) | **1** (Element) | -| `.page-title` | (0, 0, 1, 0) | **10** (Class) | -| `#header h1` | (0, 1, 0, 1) | **101** (ID + Element) | +| Selector | Score (A, B, C, D) | Total | Result | +| :--- | :--- | :--- | :--- | +| `h1` | (0, 0, 0, 1) | 1 | **Loses** | +| `.header-title` | (0, 0, 1, 0) | 10 | **Wins** (The class is 10 times more specific than the element.) | + +| Selector | Score (A, B, C, D) | Total | Result | +| :--- | :--- | :--- | :--- | +| `#sidebar p` | (0, 1, 0, 1) | 101 | **Wins** | +| `.card .title` | (0, 0, 2, 0) | 20 | **Loses** (ID selector is 100 points, dominating the score.) | -**Result:** The style from `#header h1` will win and be applied, even if `.page-title` appears after it in the CSS file, simply because **101 is greater than 10**. +:::tip Specificity Tip +Never use Inline Styles and try to reserve **ID selectors** (`#`) for JavaScript targeting rather than styling, as their high specificity makes CSS harder to override and maintain. +::: + +## The Power of `!important` + +The `!important` keyword is the nuclear option of CSS. When added to a declaration, it instantly makes that style rule **override all other rules**, regardless of specificity. + +```css title="styles.css" +/* This style will win over any ID, Class, or Element selector */ +p { + color: green !important; +} -:::tip Analogy +/* Even if an ID tries to override it, the !important rule wins */ +#main-content p { + color: red; /* This will be ignored */ +} +``` -Specificity is like a bidding war. An **Inline Style** is a million dollars (1000). An **ID** is a thousand dollars (100). A **Class** is a hundred dollars (10). Whoever bids more wins! +:::danger When to Avoid `!important` + +**Avoid using `!important`!** It breaks the natural cascade flow and specificity rules, making your code extremely difficult to debug and maintain. Only use it in rare cases like: + +1. Overriding third-party library styles where you can't edit the source CSS. +2. Utility classes (e.g., `.u-hidden { display: none !important; }`). ::: ------ +## 3. Inheritance: Borrowing Styles from Parents + +The final piece of the puzzle is **Inheritance**. Certain CSS properties are passed down (inherited) from a parent element to its child elements. + +### Inherited Properties + +Properties related to **text** and **typography** typically inherit: + + * `color` + * `font-family` + * `font-size` + * `line-height` + * `text-align` + +### Non-Inherited Properties + +Properties related to the **Box Model** and **Layout** do **not** inherit: + + * `margin` + * *`padding`* + * `border` + * `width` / `height` + * `background-color` + +### Inheritance Example -## 3. Inheritance: Passing Down the Genes +```html title="index.html" +
+

This paragraph inherits the font from its parent

.

+

But it DOES NOT inherit the border or padding.

+
+``` -**Inheritance** is the third principle, determining how styles flow down the document tree from parent elements to their children. +The browser applies the `font-family` to the `

` elements, but since `border` is not inherited, the `

` tags will not have a border unless one is specifically declared for them. -Some properties are naturally **inherited** (passed down), while others are not. +## Interactive Cascade Order Demo -### Properties that Inherit +This interactive example shows how **Specificity** (ID vs. Class) and **Source Order** (last rule wins) determine the final style. - * **Text and Font properties** generally inherit: `color`, `font-family`, `font-size`, `line-height`, `text-align`. - * If you set the `font-family` on the `` element, all paragraphs and headings inside the `` will automatically use that font. +In the CSS panel, try changing the color values and observe which rule wins based on the selector's power. -### Properties that Do Not Inherit + - * **Box Model properties** generally do not inherit: `margin`, `padding`, `border`, `width`, `height`. - * If you set a `border: 2px solid black;` on the `

`, its child elements will *not* automatically get that border. This makes sense, as you wouldn't want every nested element to inherit its parent's spacing\! -### Controlling Inheritance +### Observations -You can force any property to inherit or not using these special keywords: +1. The first paragraph's color is **Purple** because the **ID selector (`#intro-paragraph`)** has the highest Specificity score (100), overriding the Class (`.main-text`, score 10) and Element (`p`, score 1) selectors. +2. The `font-weight` is **Bold** because it is set by the Class selector (Rule 2), and the ID selector (Rule 3) does not attempt to change the `font-weight`, allowing the inherited property to apply. +3. The second paragraph (which has no class or ID) should take the color of the **last `p` rule defined in the CSS** if they were the only ones present. However, because the class and ID rules are present, they dominate the first paragraph. -| Keyword | Purpose | -| :--- | :--- | -| `inherit` | Forces a child element to take the computed value of the parent element (even if it normally wouldn't inherit). | -| `initial` | Resets the property to its default browser value. | -| `unset` | Resets the property to either the inherited value (if it's an inherited property) or the initial value (if it's not). | +**The Cascade is a complex dance of Specificity first, and Source Order second.** \ No newline at end of file diff --git a/docs/css/basics/external.mdx b/docs/css/basics/external.mdx index 0078355..b80ff36 100644 --- a/docs/css/basics/external.mdx +++ b/docs/css/basics/external.mdx @@ -114,3 +114,12 @@ The Cascade is more complex, involving **Specificity** (which we'll cover in a f | **Inline** | Inside the element's `style` attribute. | No | Single element, quick debugs, HTML emails. | | **Internal** | Inside the `