alpinejs-highlight v1.1.0
Alpine.js Highlight
Flexible text highlighting for Alpine.js 🔦
Features
- 💅 Powerful Highlighting: Highlight text matches with multiple pattern types (strings, regex, index ranges)
- 🎨 Multiple Highlight Sets: Create separate highlight groups with custom styling
- ⚙️ Advanced Options: Case-insensitive matching, find all occurrences, accent folding and minimum length modifiers
- 🔍 Match Information: Access count and position data through the
$matches
magic helper - 🔮 Auto Adaptation: Uses modern CSS Highlight API with fallback for older browsers
Installation
With a CDN
<!-- Alpine Highlight Plugin (must be before Alpine.js) -->
<script src="https://unpkg.com/alpinejs-highlight@latest/dist/highlight.min.js" defer></script>
<!-- Alpine.js -->
<script src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js" defer></script>
With a Package Manager
npm install alpinejs-highlight
# or
yarn add alpinejs-highlight
import Alpine from 'alpinejs'
import highlight from 'alpinejs-highlight'
Alpine.plugin(highlight)
Alpine.start()
Basic Usage
Alpine.js Highlight adds a new x-highlight
directive that lets you highlight text within elements. The directive accepts different types of input patterns and highlights matching text. The plugin automatically detects content changes and updates highlights accordingly.
The plugin works in two modes: 1. Using the modern CSS Highlight API (preferred) 2. Falling back to mark elements for older browsers
Here's a simple example:
<div x-data="{ term: 'mark' }">
<p x-highlight="term">
A highlighter pen helps mark important passages of text.
</p>
</div>
Result: "A highlighter pen helps mark important passages of text."
The search term can be dynamically updated, and the highlights will automatically refresh to match the new term.
The plugin also monitors changes to the text content itself. In the following example, whenever the number 29
appears in the newly generated random numbers, it will be automatically highlighted without requiring any additional code:
<div x-data="{
myLuckyNumber: 29,
randomNumbers: '10 29 85 29 47 63 29 91'
}">
<p x-text="randomNumbers" x-highlight.all="myLuckyNumber"></p>
<button @click="randomNumbers = Array.from({length: 10}, () => Math.floor(Math.random() * 100)).join(' ')">
Generate New Numbers
</button>
</div>
Styling Highlights
The Alpine.js Highlight plugin provides two different methods for styling your highlighted text, depending on browser capabilities. Modern browsers will use the CSS Highlight API, while browsers not supporting the CSS Highlight API fall back to using mark elements. You'll want to define styles for both approaches to ensure consistent highlighting across all browsers.
Modern browsers (CSS Highlight API)
::highlight(x-highlight) {
background-color: hotpink;
text-decoration: underline;
}
Fallback (uses mark elements)
mark.x-highlight {
background-color: hotpink;
text-decoration: underline;
}
x-highlight
The x-highlight
directive is used to highlight text within elements based on a given query.
Basic Syntax
<p x-highlight="expression">Text content to be highlighted</p>
Supported Input Types
Strings: Find and highlight string matches
<p x-highlight="'highlight'">Text with highlight marker</p>
Result: "Text with highlight marker"
Dynamic Variables: Highlight based on model data
<p x-highlight="searchTerm">Search results will be highlighted</p>
Regular Expressions: Use regex patterns for more complex matching
<p x-highlight="/mark\w*/g">The marked markings were remarkable</p>
Result: "The marked markings were remarkable"
Arrays of Patterns: Highlight multiple terms at once
<p x-highlight="['note', 'mark']">Make a note and mark it important</p>
Result: "Make a note and mark it important"
Index Ranges: Highlight by character position
<p x-highlight="[7, 15]">Color highlighted text in documents</p>
Result: "Color highlighted text in documents"
Multiple Ranges: Highlight multiple text ranges
<p x-highlight="[[0, 5], [16, 20]]">Color highlighted text in documents</p>
Result: "Color highlighted text in documents"
Modifiers
The x-highlight
directive supports several modifiers to customize highlighting behavior:
.all
: Find all occurrences (by default only the first match is highlighted)<p x-highlight.all="'e'">Emphasize every essential element</p>
Result: "Emphasize every essential element"
.nocase
: Case-insensitive matching<p x-highlight.nocase.all="'MARK'">Marking important text with a marker</p>
Result: "Marking important text with a marker"
.min.X
: Set minimum match length (where X is a number)<p x-highlight.min.4="'mar'">Marking bookmarks with highlight markers</p>
Result: "Marking bookmarks with highlight markers" (no highlights, would only highlight if a fourth character is added)
.fold
: Accent folding (ignores diacritical marks)<p x-highlight.fold="'resume'">Make a résumé with highlighted sections</p>
Result: "Make a résumé with highlighted sections"
Combining Modifiers
You can combine multiple modifiers to create sophisticated highlighting:
<p x-highlight.all.nocase.min.4.fold="searchTerm">
Annotated text with potential matches
</p>
Named Highlight Sets
If the first modifier after the directive name is not one of the functional modifiers (all
, nocase
, min
, fold
), it is interpreted as a naming modifier that creates a custom highlight set.
<p x-highlight.cool="'important'" x-highlight.warning="'caution'">
This important message requires caution when handling
</p>
Possible result: "This important message requires caution when handling" (with customizable styles for each highlight set)
These named sets create CSS classes or highlight registrations with the name pattern x-highlight-{name}
. For example, the modifier .warning
creates a highlight set called x-highlight-warning
.
You can style these named sets in your CSS:
For modern browsers (CSS Highlight API)
::highlight(x-highlight-cool) {
background-color: skyblue;
}
::highlight(x-highlight-warning) {
background-color: orangered;
text-decoration: underline;
}
For fallback (mark elements)
mark.x-highlight-cool {
background-color: skyblue;
}
mark.x-highlight-warning {
background-color: orangered;
text-decoration: underline;
}
This approach allows you to create multiple distinct highlight styles on the same page for different types of content or importance levels.
$matches
Magic Helper
The $matches
magic helper allows you to access information about the highlighted matches. It provides count and position data for highlighted content within the current Alpine data context.
Basic Usage
<div x-data="{ term: 'note' }">
<p x-highlight.all="term">Make a note of these notes and notation marks</p>
<div>
Found <span x-text="$matches().count"></span> matches
</div>
</div>
Options Configuration
The $matches
magic accepts an options object with the following properties:
selector
: Target specific element(s) by CSS selector (e.g.,'#content'
)set
: Retrieve matches from a specific highlight set (e.g.,'yellow'
)bounds
: Include position information for each match when set totrue
Targeting Specific Elements
<p id="content" x-highlight.all="term">A noted notation about notes</p>
<div>
Matches in content: <span x-text="$matches({ selector: '#content' }).count"></span>
</div>
Accessing Specific Highlight Sets
<p x-highlight.yellow="'note'" x-highlight.red="'mark'">
Notes and markers for annotation
</p>
<div>
Yellow matches: <span x-text="$matches({ set: 'yellow' }).count"></span>
</div>
Getting Match Details and Bounds
For advanced usage, $matches
provides detailed information about each match:
<div x-data="{ term: 'highlight' }">
<p x-highlight.all="term">Text with highlights</p>
<button @click="
let result = $matches({ bounds: true });
console.log(result.matches[0].text); // 'highlight'
console.log(result.matches[0].index); // position in text
console.log(result.matches[0].bounds); // DOM position
">
Show Match Details
</button>
</div>
Combining Options
You can combine multiple options in a single call:
<button @click="
let specificMatches = $matches({
selector: '#paragraph-id',
set: 'primary',
bounds: true
});
console.log(specificMatches);
">
Analyze Specific Matches
</button>
Browser Support
Alpine.js Highlight uses the modern CSS Highlight API when available, with an automatic fallback to a DOM-based approach for browsers with no CSS Highlight API support (notably Firefox as of March 2025).
Browser Compatibility Considerations
With the modern CSS Highlight API, multiple highlight sets can be displayed simultaneously on the same content. Each set applies its styling independently, allowing for overlapping highlights with combined visual effects.
However, when using the fallback implementation (for browsers without CSS Highlight API support), there are some limitations:
- Single Active Set Per Text Node: In the fallback mode, only one highlight set can be shown at a time for any given text node. When a new highlight set is added to text that already has highlights, the previous highlights will be removed.
- Multiple Ranges Support: Each highlight set can still include multiple ranges within the same text.
- Multiple Elements Support: Different elements can each have their own highlight sets, even with the fallback implementation.
For the most consistent experience across browsers, consider these best practices until the CSS Highlight API is fully adopted across all major browsers:
- Design your application to work with the fallback's single-set-per-node limitation
- Use separate elements for content that needs different highlight sets
Contributing
If you encounter any issues or have suggestions, please open an new issue.
License
MIT License © 2025 Timo Rychert