Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
161 changes: 160 additions & 1 deletion docs/css/advanced-features/cascade-layers.mdx
Original file line number Diff line number Diff line change
@@ -1 +1,160 @@
<ComingSoon />
---
title: "CSS Cascade Layers (@layer)"
description: "Learn how to use the @layer rule to organize CSS styles into distinct layers, gaining control over the cascade and solving specificity conflicts in complex stylesheets."
keywords: [CSS layers, '@layer', cascade control, specificity, CSS organization, component layers, framework layers, layer precedence, unlayered styles]
tags: [CSS layers, '@layer', cascade control, specificity, CSS organization, component layers, framework layers, layer precedence, unlayered styles]
sidebar_label: Cascade Layers
---

CSS Cascade Layers, introduced by the **`@layer`** at-rule, provide a powerful mechanism for organizing CSS and controlling the **cascade** more predictably. They solve a long-standing problem in large-scale CSS projects: how to manage specificity conflicts between different sources of styles (e.g., framework, base, components, and utilities).

**The Core Concept:** Styles within a higher-priority layer will *always* win over styles in a lower-priority layer, **regardless of the selector's specificity** within those layers.

<AdsComponent />
<br />

## 1. The Cascade Layer Order

The final result of a style depends on a fixed order of precedence. Cascade Layers slot into the standard cascade but allow you to define a sub-order for your own styles.

**The Key Layer Precedence Rule:**

* **Earlier layers have lower priority (less important).**
* **Later layers have higher priority (more important).**

This means a simple selector in a late-defined layer can override a highly specific selector in an early-defined layer.

### Order of Author Styles (Lowest to Highest Priority)

1. **Styles within the first defined `@layer`** (e.g., `reset`).
2. **Styles within later defined `@layer`s** (e.g., `utilities`).
3. **Unlayered Styles** (CSS not wrapped in any `@layer` block).
4. **Author `!important` declarations.**


## 2. Defining and Ordering Layers

You must define the order of your layers using a single `@layer` statement, typically placed at the very top of your CSS file.

### 2.1. Defining the Order

```css
/* 1. Define the layer order (Lowest to Highest Precedence) */
@layer reset, framework, base, components, utilities;
```

In this setup: `reset` has the lowest priority, and `utilities` has the highest priority among the layers.

<AdsComponent />
<br />

### 2.2. The Specificity vs. Layer Rule

This is the most critical concept to understand:

> **Layer Order Trumps Specificity:** The specificity of a selector only matters *within* its own layer. Once two properties conflict across two different layers, the layer order determines the winner, ignoring specificity.

:::tip Layer Wins
Consider two rules:
1. `.box` (`specificity: 0,1,0`) in the `base` layer.
2. `#box-id` (`specificity: 1,0,0`) in the `utilities` layer.

If `utilities` is defined *after* `base`, the simple `.box` utility will override the highly specific `#box-id` selector, because the `utilities` layer has higher precedence. This is how layers flip the cascade.
:::

### 2.3. Creating Layer Blocks

You then wrap your styles in named `@layer` blocks. You can define layers across multiple files or multiple blocks in the same file; the browser will stitch them together based on the initial ordering statement.

```css title="styles.css"
/* -- 1. Reset Layer (Lowest Priority) -- */
@layer reset {
/* This universal selector style is easily overridden by any other layer. */
* {
box-sizing: border-box;
}
}

/* -- 2. Components Layer (Mid Priority) -- */
@layer components {
/* Specific component style */
.card-title {
color: var(--theme-color);
}
}
```

## 3. Unlayered Styles (The Override)

Styles that are **not** included in any `@layer` block are referred to as **unlayered styles**.

Unlayered styles always have a higher precedence than **all** layered styles, regardless of their position in the file or the layer order.

:::warning Unlayered Priority
Use unlayered styles sparingly, typically only for final, non-negotiable overrides or small third-party snippets where integrating them into a layer is impractical. Relying heavily on unlayered styles defeats the purpose of managing the cascade with layers. The goal should be to make 99% of your styles layered.
:::

```css title="styles.css"
/* This style is NOT wrapped in @layer. Specificity: 0,1,0 */
.final-override {
/* This will win over ALL layered styles, even if the selector is simpler. */
background-color: green;
}

/* This is a layered style that loses to the unlayered style above. Specificity: 0,1,0 */
@layer utilities {
.final-override {
background-color: red;
}
}
```

<AdsComponent />
<br />

## 4. Layer Organization and Naming

A common layer strategy is to move from the least specific, broadest styles to the most specific, overriding styles.

| Layer Name | Typical Content | Priority | Role |
| :--- | :--- | :--- | :--- |
| **`reset`** | CSS resets (e.g., normalize.css), global box-sizing. | Lowest | Provides a clean slate. |
| **`framework`** | Third-party libraries (Tailwind base, Bootstrap). | Low | Imports external defaults. |
| **`base`** | Element selectors (`h1`, `p`, `a`), custom fonts, root variables. | Mid-Low | Defines project defaults. |
| **`components`** | Reusable, complex class selectors (e.g., `.modal`, `.card`). | Mid-High | Defines component structure. |
| **`utilities`** | Single-purpose, overriding classes (e.g., `.u-hidden`, `.u-text-red`). | Highest | Ensures utility classes always win. |

### Nested and Imported Layers

Layers can be nested, and styles can be imported directly into a layer, making framework integration seamless.

:::info Layer Nesting
Nesting layers helps organize large component libraries (e.g., separating forms from navigation).

```css title="styles.css"
/* Initial layer declaration must include the top level: */
@layer framework, components;

/* Importing an external file into the 'framework' layer */
@import url('bootstrap.css') layer(framework);

/* Defining a nested layer within components */
@layer components.forms {
/* Styles for form components */
.input-field { border-color: gray; }
}
```
Styles in `components.forms` have the same precedence as `components` styles.
:::

<AdsComponent />
<br />

## Interactive CSS Layers Demo

This example demonstrates the precedence: The `utility` layer is defined later than the `component` layer, so the utility's style always wins. The `unlayered` style wins over both.

<CodePenEmbed
title="Interactive CSS Layers Demo"
penId="zxqajqv"
/>
115 changes: 114 additions & 1 deletion docs/css/advanced-features/css-functions.mdx
Original file line number Diff line number Diff line change
@@ -1 +1,114 @@
<ComingSoon />
---
title: "Advanced CSS Functions (calc, clamp, min, max)"
description: "Explore essential CSS functions like calc(), clamp(), min(), and max() for dynamic sizing, combining fixed and fluid units to create highly robust and mathematical layouts."
keywords: [CSS functions, calc, clamp, min, max, dynamic sizing, mathematical layouts, fluid typography, responsiveness]
tags: [CSS functions, calc, clamp, min, max, dynamic sizing, mathematical layouts, fluid typography, responsiveness]
sidebar_label: CSS Functions
---

CSS is no longer a static styling language. Modern CSS includes powerful functions that allow you to perform calculations and create dynamic, responsive values that adapt to the browser environment.

The four most important functions for creating robust layouts are `calc()`, `clamp()`, `min()`, and `max()`.

<AdsComponent />
<br />

## 1. `calc()`: Mathematical Calculations

The `calc()` function allows you to perform basic arithmetic (addition, subtraction, multiplication, division) within CSS property values.

Its primary benefit is the ability to mix different unit types (e.g., mixing fixed pixels with fluid percentages or viewport units).

### 1.1. Syntax and Rules

```css title="styles.css"
/* Example: 50% of the parent width minus a fixed 20px of padding */
width: calc(50% - 20px);
```

**Crucial Rule for `calc()`:**

* **Spaces are mandatory** around the `+` and `-` operators. `calc(50% - 20px)` is correct. `calc(50%-20px)` will break.
* Spaces are optional for `*` and `/`.

### 1.2. Practical Use Cases

| Use Case | Example | Description |
| :--- | :--- | :--- |
| **Gutter Management** | `width: calc(100% / 3 - 2rem);` | Calculates the width of three equal columns, subtracting necessary margin/gap space. |
| **Viewport Offset** | `height: calc(100vh - 80px);` | Sets an element height to the full viewport height minus a fixed header height. |
| **Variable Manipulation** | `padding: calc(var(--base-unit) * 1.5);` | Scales a CSS variable by a factor. |

<AdsComponent />
<br />

## 2. `clamp()`: Bounding Fluid Values

The `clamp()` function pins a value between a minimum and a maximum size. This is the cornerstone of modern, fluid typography.

`clamp()` takes three arguments: **Minimum Value, Preferred (Fluid) Value, Maximum Value**.

```css title="styles.css"
/* Example: Font size that scales between 16px and 24px based on viewport width
clamp( MIN, PREFERRED, MAX )
```

### 2.1. Fluid Typography Example

```css title="styles.css"
h1 {
/* Font size will never be smaller than 3rem,
never larger than 5rem, and will scale fluidly in between. */
font-size: clamp(3rem, 2rem + 2vw, 5rem);
}
```

* If the result of `2rem + 2vw` is less than `3rem`, the browser uses `3rem`.
* If the result is greater than `5rem`, the browser uses `5rem`.
* Otherwise, the browser uses the fluid value.

## 3. `min()` and `max()`: Setting Limits

The `min()` and `max()` functions allow you to choose the smallest or largest value from a comma-separated list of expressions. This is excellent for creating resilient components that avoid common layout pitfalls.

### 3.1. `min()`: Selecting the Smaller Value

`min(value1, value2, ...)` chooses the smallest value.

**Use Case: Preventing Element Overflow.**
Imagine you want a container to be $50\%$ of the screen width, but never wider than a fixed 800px.

```css title="styles.css"
.container {
/* The width will be 50% OR 800px, whichever is smaller.
This effectively sets the max-width dynamically. */
width: min(50vw, 800px);
}
```

<AdsComponent />
<br />

### 3.2. `max()`: Selecting the Larger Value

`max(value1, value2, ...)` chooses the largest value.

**Use Case: Ensuring Minimum Size.**
Imagine you want a sidebar to be 20% of the screen width, but it must be at least 250px wide to hold its content.

```css title="styles.css"
.sidebar {
/* The width will be 20% OR 250px, whichever is larger.
This effectively sets the min-width dynamically. */
width: max(20vw, 250px);
}
```

## Interactive CSS Functions Demo

This example uses `calc()`, `min()`, and `max()` to demonstrate dynamic sizing in a layout.

<CodePenEmbed
title="Interactive CSS Functions Demo"
penId="XJdYZMz"
/>
Loading