Markdown source
Interactive Features Showcase Markdown source
Readable source view for humans. The raw Markdown endpoint remains available for crawlers and agent readers.
---
title: "Interactive Features Showcase"
description: "All the interactive components, code features, and eye candy available in krowdev articles."
kind: snippet
maturity: evergreen
confidence: high
origin: ai-assisted
author: "Agent"
directedBy: "krow"
tags: [astro, reference]
published: 2026-03-17
modified: 2026-04-21
wordCount: 744
readingTime: 4
related: [astro-mental-model]
url: https://krowdev.com/snippet/interactive-features-showcase/
---
## Agent Context
- Canonical: https://krowdev.com/snippet/interactive-features-showcase/
- Markdown: https://krowdev.com/snippet/interactive-features-showcase.md
- Full corpus: https://krowdev.com/llms-full.txt
- Kind: snippet
- Maturity: evergreen
- Confidence: high
- Origin: ai-assisted
- Author: Agent
- Directed by: krow
- Published: 2026-03-17
- Modified: 2026-04-21
- Words: 744 (4 min read)
- Tags: astro, reference
- Related: astro-mental-model
- Content map:
- h2: Code Blocks
- h2: Line Highlighting
- h2: Diff Notation
- h2: Editor and Terminal Frames
- h2: Collapsible Sections
- h2: Callout Boxes
- h2: Challenge Blocks
- h2: Code View Tabs
- h2: Sources
- Crawl policy: same canonical content is exposed through HTML, Markdown, and llms-full; no crawler-specific content gate.
This page demonstrates every interactive feature available when writing krowdev content. Use it as a reference when creating new articles. If you're new to how Astro renders these components, start with [the mental model](/guide/astro-mental-model/) — everything here is compiled to static HTML at build time. If the styling here ever looks odd, [Bare Element Selectors vs Library HTML](/snippet/bare-selectors-vs-library-html/) and [CSS Collision Visualized](/snippet/css-collision-visualized/) explain the most common global-CSS collisions.
## Code Blocks
Every fenced code block automatically gets a **language badge**, a **copy button** (hover to reveal), and proper Catppuccin syntax highlighting.
```python
def fibonacci(n):
"""Generate the first n Fibonacci numbers."""
a, b = 0, 1
for _ in range(n):
yield a
a, b = b, a + b
for num in fibonacci(10):
print(num)
```
```bash
# Install dependencies and build
npm install
npm run build
npm run preview
```
```sql
SELECT users.name, COUNT(posts.id) AS post_count
FROM users
LEFT JOIN posts ON users.id = posts.author_id
GROUP BY users.name
HAVING post_count > 5
ORDER BY post_count DESC;
```
## Line Highlighting
Use `mark={lines}` in the code fence meta to highlight specific lines:
```javascript mark={2-3}
function greet(name) {
const greeting = `Hello, ${name}!`;
console.log(greeting);
return greeting;
}
```
## Diff Notation
Use `ins={lines}` and `del={lines}` to show additions and removals:
```javascript del={5} ins={6-7}
function createUser(name, email) {
return {
name,
email,
role: 'viewer',
role: 'editor',
createdAt: Date.now(),
};
}
```
## Editor and Terminal Frames
Code blocks auto-detect their frame type. Use `title="filename"` for editor tabs:
```js title="src/utils/helper.js"
export function greet(name) {
return `Hello, ${name}!`;
}
```
Shell languages get terminal frames automatically:
```bash title="Installing dependencies"
npm install astro-expressive-code
```
## Collapsible Sections
Use `collapse={lines}` to collapse less-important lines:
```typescript collapse={1-4}
interface BlogPost {
title: string;
date: Date;
tags: string[];
content: string;
draft: boolean;
}
function publishPost(post: BlogPost): void {
if (post.draft) {
throw new Error('Cannot publish a draft');
}
// ... publish logic
}
```
## Callout Boxes
Eight types, each with a Catppuccin accent color:
:::note
**Notes** provide additional context. They use the blue accent.
:::
:::tip
**Tips** suggest best practices. They use the green accent.
:::
:::info
**Info** blocks share background details. They use the sapphire accent.
:::
:::warning
**Warnings** flag common mistakes. They use the yellow accent.
:::
:::danger
**Danger** blocks mark breaking or destructive actions. They use the red accent.
:::
:::caution
**Caution** blocks advise careful consideration. They use the peach accent.
:::
<strong>Analogies</strong> map to familiar concepts. Think of Astro components like Python functions — they take arguments (props) and return a result (HTML).
<strong>Key insights</strong> highlight the most important takeaway. This is what you'd underline in a textbook.
## Challenge Blocks
Interactive exercises that expand on click:
**Challenge: Build a greeting component**
Create a `Greeting.astro` component that:
1. Accepts a `name` prop (string)
2. Renders `<h2>Hello, {name}!</h2>`
3. Uses a scoped style to color the text with `var(--accent)`
```astro
---
interface Props {
name: string;
}
const { name } = Astro.props;
---
<h2>Hello, {name}!</h2>
<style>
h2 { color: var(--accent); }
</style>
```
**What happens if you forget the Props interface?**
TypeScript won't catch incorrect prop usage at build time. You'll get `undefined` instead of a type error. Always define the interface — it's your safety net.
## Code View Tabs
The Source / Compiled / Rendered pattern for showing how Astro transforms code:
<p class="cv-label">src/components/Badge.astro</p>
<nav class="cv-tabs" role="tablist">
<button class="cv-tab active" role="tab" data-tab="source" aria-selected="true">Source</button>
<button class="cv-tab" role="tab" data-tab="compiled" aria-selected="false">Compiled</button>
<button class="cv-tab" role="tab" data-tab="rendered" aria-selected="false">Rendered</button>
</nav>
<div class="cv-panel active" data-panel="source" role="tabpanel">
```astro
---
interface Props { label: string; color?: string; }
const { label, color = 'var(--accent)' } = Astro.props;
---
<span class="badge" style={`--badge-color: ${color}`}>
{label}
</span>
<style>
.badge {
display: inline-flex;
padding: 0.15rem 0.6rem;
border-radius: 999px;
font-size: 0.75rem;
font-weight: 600;
color: var(--badge-color);
border: 1px solid var(--badge-color);
background: color-mix(in srgb, var(--badge-color) 10%, transparent);
}
</style>
```
<div class="cv-panel" data-panel="compiled" role="tabpanel">
```html
<span class="badge" style="--badge-color: var(--accent)"
data-astro-cid-x7q2k1>
beginner
</span>
<style>
.badge[data-astro-cid-x7q2k1] {
display: inline-flex;
padding: 0.15rem 0.6rem;
/* ... scoped to this component only */
}
</style>
```
<div class="cv-panel" data-panel="rendered" role="tabpanel">
The compiled output shows Astro's scoped CSS in action. The `data-astro-cid-x7q2k1` attribute uniquely identifies this component instance, ensuring styles never leak to other elements.
## Sources
- Astro Docs, [MDX integration](https://docs.astro.build/en/guides/integrations-guide/mdx/)
- Astro Docs, [Styles and CSS](https://docs.astro.build/en/guides/styling/)
- Expressive Code, [Installing Expressive Code](https://expressive-code.com/installation/)
- Expressive Code, [Collapsible Sections](https://expressive-code.com/plugins/collapsible-sections/)