Markdown source

CSS Collision Visualized Markdown source

Readable source view for humans. The raw Markdown endpoint remains available for crawlers and agent readers.

---
title: "CSS Collision Visualized"
description: "Interactive demo of bare element selectors colliding with library HTML — three defects from one rule, shown against common library producers."
kind: snippet
maturity: budding
confidence: high
origin: ai-drafted
author: "Agent"
directedBy: "krow"
tags: [css, astro, patterns]
published: 2026-04-18
modified: 2026-04-21
wordCount: 420
readingTime: 2
related: [bare-selectors-vs-library-html, astro-mental-model]
url: https://krowdev.com/snippet/css-collision-visualized/
---
## Agent Context

- Canonical: https://krowdev.com/snippet/css-collision-visualized/
- Markdown: https://krowdev.com/snippet/css-collision-visualized.md
- Full corpus: https://krowdev.com/llms-full.txt
- Kind: snippet
- Maturity: budding
- Confidence: high
- Origin: ai-drafted
- Author: Agent
- Directed by: krow
- Published: 2026-04-18
- Modified: 2026-04-21
- Words: 420 (2 min read)
- Tags: css, astro, patterns
- Related: bare-selectors-vs-library-html, astro-mental-model
- Content map:
  - h2: Worked example: pre vs a syntax-highlighter frame
  - h2: Same cascade, other common producers
  - h2: Fix ladder
  - h2: Sources
- Crawl policy: same canonical content is exposed through HTML, Markdown, and llms-full; no crawler-specific content gate.

import CSSCollisionDemo from '../../src/components/CSSCollisionDemo.svelte';
import CollisionCases from '../../src/components/CollisionCases.svelte';

Bare element selectors in a global stylesheet cascade into HTML emitted by third-party libraries. Box-model properties on different boxes stack rather than override, so a single well-meaning `pre {}` or `a {}` rule can produce visibly doubled padding, doubled borders, mismatched backgrounds, or structural elements that inherit prose styling. See [Bare Element Selectors vs Library HTML](/snippet/bare-selectors-vs-library-html/) for the full reference table and diagnostic.

The same syntax-highlighter and tabbed-code wrappers appear on [Interactive Features Showcase](/snippet/interactive-features-showcase/), which makes this collision easier to reproduce in a real article context.

## Worked example: `pre` vs a syntax-highlighter frame

Syntax highlighters (Expressive Code, Shiki frames, Prism plugins, etc.) wrap code in an outer `<pre>` and an inner container with its own padding, border, and background. A bare `pre { padding, border, background }` rule in the global stylesheet lands on the outer element — and produces three defects at once:

1. **Padding stacks.** The outer `<pre>` gets the global padding; the inner code line already had the highlighter's padding.
2. **Border doubles.** The frame titlebar already draws a bottom border; the global rule draws a top border right beneath it.
3. **Background mismatches.** The frame chrome uses the highlighter's theme background; the global rule paints the outer `<pre>` with a slightly different token.

<CSSCollisionDemo client:visible />

**Fix.** If no hand-authored `<pre>` appears anywhere on the site (i.e. every `<pre>` is highlighter output), delete the bare rule. The library owns inner styling via its own config. Keep one declaration for outer block rhythm:

```css
.expressive-code {
  margin: 1.5rem 0;
}
```

If hand-authored `<pre>` *does* appear, scope the rule to a content wrapper instead:

```css
.content :global(pre:not([class])) {
  /* your prose styling */
}
```

## Same cascade, other common producers

The `pre` case is visible because three box-model properties stack at once. The same cascade shape applies elsewhere — one property at a time, so the collision is quieter but just as real. Each card below toggles between the broken state (global rule applied) and the fixed state (rule scoped to prose or removed).

<CollisionCases client:visible />

## Fix ladder

1. **Delete** when no legitimate prose consumer exists.
2. **Scope to a content wrapper class** — move the rule into a layout-scoped `<style>` with `:global()` targeting your rendered-markdown region. Astro-native.
3. **`:not()` exclusion** — per-library, doesn't scale.

See also: [Bare Element Selectors vs Library HTML](/snippet/bare-selectors-vs-library-html/) for the full inventory and diagnostic.

## Sources

- MDN, [Specificity](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_cascade/Specificity)
- MDN, [The box model](https://developer.mozilla.org/docs/Learn_web_development/Core/Styling_basics/Box_model)
- Astro Docs, [Styles and CSS](https://docs.astro.build/en/guides/styling/)