# CSS-Inspired Specificity in Wasot Selectors

## Overview

Specificity is a weight that applies to a given [selector](./selectors.md), determining which rule takes precedence when multiple selectors could match the same element. The Wasot selector system uses a specificity calculation inspired by CSS rules, but adapted for our selector-only context (no inline styles).

## Specificity Calculation

Specificity is calculated using a three-component weight system: `(a, b, c)`

- **a**: Number of ID selectors
- **b**: Number of class selectors, attribute selectors, and pseudo-classes
- **c**: Number of type selectors and pseudo-elements

Note: Unlike CSS, Wasot selectors don't include inline styles since we're dealing with selectors only, not style declarations.

### Component Values

#### ID Selectors (a)
- `#header` adds 1 to component a
- Each ID selector in the chain adds to this count

#### Class, Attribute, and Pseudo-class Selectors (b)
- `.highlight` adds 1 to component b
- `[disabled]` adds 1 to component b  
- `[href="https://example.com"]` adds 1 to component b
- `:first-child` adds 1 to component b
- `:nth-child(3)` adds 1 to component b
- `:hover`, `:focus`, etc. add 1 to component b

#### Type Selectors (c)
- `div`, `paragraph`, `section` each add 1 to component c
- The universal selector `*` has a specificity of 0

### Special Cases

#### :not() Pseudo-class
The `:not()` pseudo-class itself doesn't add to specificity, but the selectors inside it do:
- `:not(.disabled)` has specificity (0,1,0) - from the `.disabled` class
- `:not(#main)` has specificity (1,0,0) - from the `#main` ID
- `:not(div)` has specificity (0,0,1) - from the `div` type

#### Combinators
Combinators (`>`, ` `, `+`, `~`) do not affect specificity:
- `div > p` has specificity (0,0,2) - two type selectors
- `#main .content` has specificity (1,1,0) - one ID, one class

## Examples

### Simple Selectors
```
*                       (0,0,0)
div                     (0,0,1)
.warning                (0,1,0)
#main                   (1,0,0)
```

### Compound Selectors
```
div.warning             (0,1,1)  - 1 class, 1 type
#main.active            (1,1,0)  - 1 ID, 1 class
div#main.active         (1,1,1)  - 1 ID, 1 class, 1 type
```

### Complex Selectors
```
section > p.intro                   (0,1,2)  - 1 class, 2 types
#header nav ul li                   (1,0,3)  - 1 ID, 3 types
.nav-item:hover:not(.disabled)      (0,3,0)  - 3 classes/pseudo-classes
div[role="navigation"].primary      (0,2,1)  - 1 attribute, 1 class, 1 type
```

## Comparison Rules

Specificities are compared component by component from left to right:

1. Compare component a (IDs)
2. If equal, compare component b (classes/attributes/pseudo-classes)
3. If equal, compare component c (types)

Examples:
- `(1,0,0)` beats `(0,10,10)` - ID beats any number of classes/types
- `(0,2,1)` beats `(0,1,5)` - More classes beat more types
- `(0,1,1)` equals `(0,1,1)` - Same specificity, order matters

## Implementation Notes

The specificity calculation in Wasot:
1. Walks through the [AST](./ast.md) of a parsed selector
2. Counts each type of selector component
3. Returns a tuple `(a, b, c)` for easy comparison
4. Supports all selector types defined in `src/parsers/selectors/ast.rs` (see [parser notes](./selector_parser_notes.md))
5. For OR selectors (comma-separated), returns the maximum specificity

## Use Cases

Specificity is crucial for:
- Determining which rule applies when multiple selectors match
- Implementing cascade resolution in styling systems
- Debugging selector conflicts
- Optimizing selector performance (lower specificity = better performance)

## Best Practices

1. **Keep specificity low**: Use the minimum specificity needed
2. **Avoid ID selectors**: They have high specificity and are hard to override
3. **Use classes**: Classes provide good specificity without being too specific
4. **Be consistent**: Use similar specificity levels for related rules
5. **Document high specificity**: When high specificity is needed, explain why