
neat-annotations is a pure CSS annotation component that places hand-drawn arrows and handwritten labels around inline content.
It’s good for notes, callouts, review marks, feature explanations, and other visual cues that need a sketch-style appearance.
Features:
- Pure CSS annotation rendering with no JavaScript initialization.
- Eight arrow directions around inline targets.
- Handwritten labels sourced from HTML data.
- Five static colors, a warm gray default, and an animated rainbow theme.
- Highlight-only mode for marker-style emphasis.
- Per-element control over spacing, label width, position, tilt, font, and colors.
- Nested annotations for multiple notes around one target.
How To Use It:
Installation
Load the stylesheet from jsDelivr. You can also download neat-annotations.css and serve it from your project.
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/syabro/neat-annotations/neat-annotations.css" >
Add the font before your own stylesheet when you want the handwritten style.
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Shantell+Sans:wght@400;500;600&display=swap" >
Basic Usage
Add ann to the inline target. Choose a direction class and a color class, then store the visible label in data-note.
ann-n draws an arrow that points north toward the target. Its label appears below the annotated text.
<p>
The new search index returns
<span
class="ann ann-n ann-blue"
data-note="cached for faster reloads"
>
results instantly
</span>.
</p>
Arrow Direction Classes
| Class | Label placement |
|---|---|
ann-n | Below the target. |
ann-ne | Below and left of the target. |
ann-e | Left of the target. |
ann-se | Above and left of the target. |
ann-s | Above the target. |
ann-sw | Above and right of the target. |
ann-w | Right of the target. |
ann-nw | Below and right of the target. |
Color Themes and Custom Colors
The default theme uses warm gray. Add one of these classes when the annotation needs a fixed accent:
ann-amberann-blueann-greenann-redann-purpleann-rainbow
The rainbow theme cycles through hues. Its animation runs only when the user has not requested reduced motion.
<p>
The
<span class="ann ann-s ann-red" data-note="requires review">
API response
</span>
still contains a deprecated field.
</p>
Set --ann-color directly when the built-in themes do not match the page palette.
<span class="ann ann-w" data-note="custom project color" style="--ann-color: #0f766e" > production status </span>
Highlight Text Without a Label
Omit the direction class and data-note to keep only the marker-style background.
<p> Update the <span class="ann ann-amber">migration guide</span> before release. </p>
Preserve the Target’s Existing Background
The base class adds a highlight behind the target. Add ann-no-mark when the nested element already has its own background color.
<span class="ann ann-n ann-purple ann-no-mark" data-note="ready for release" > <span class="status-badge">Stable</span> </span>
Add Two Notes to One Target
Nest annotations when separate notes need to point toward the same phrase from different sides. Check the surrounding line height and container edges before stacking notes. Each arrow and label occupies visual space outside the target.
<span
class="ann ann-w ann-blue ann-no-mark"
data-note="assigned to Maya"
>
<span
class="ann ann-e ann-red"
data-note="high priority"
>
checkout validation
</span>
</span>
Adjust Long Notes and Placement
Long labels wrap at 150px by default. Increase the width and offset the arrow or text when the annotation collides with nearby content.
<span
class="ann ann-n ann-green"
data-note="Confirm the rollback steps before publishing this release."
style="
--ann-label-max-width: 220px;
--ann-arrow-x: 8px;
--ann-text-x: 18px;
--ann-text-y: 10px;
"
>
release checklist
</span>
CSS Custom Properties
--ann-color: Sets the arrow and label color. Default:oklch(0.62 0.005 30).--ann-mark: Sets the target highlight. The default is a theme-aware tint derived from the annotation color.--ann-font: Sets the label font. Default:'Shantell Sans', cursive.--ann-target-gap: Sets the gap between the target and arrow. Default:5px.--ann-label-gap: Sets the gap between the arrow and label. Default:6px.--ann-lower-label-gap: Adjusts labels below the target. Default:-4px.--ann-label-max-width: Sets the label width before text wraps. Default:150px.--ann-arrow-x: Moves the arrow horizontally. Default:0px.--ann-arrow-y: Moves the arrow vertically. Default:0px.--ann-text-x: Moves the label horizontally. Default:0px.--ann-text-y: Moves the label vertically. Default:5px.--ann-rotate: Sets the label angle. Default:-4deg.
Set these properties on an individual annotation for local changes or on a parent selector for a shared project theme.
.release-note .ann {
--ann-color: #7c3aed;
--ann-font: "Comic Sans MS", cursive;
--ann-label-max-width: 190px;
--ann-rotate: -2deg;
}Alternatives:
- Animated Handdrawn Text Annotation Library – Rough Notation
- Interactive Text Annotation and Highlighting with Recogito Text Annotator
- Text Annotation And Highlighting Library – Annotate.js







