A lightweight, dependency-free library for creating beautiful animated SVG underlines with multiple trigger options.
Move your mouse over the highlighted words to see the underlines appear.
Words animate as they enter the viewport, creating engaging scroll experiences.
Click on words to trigger unique underline animations.
Use Tab key to navigate and see underlines appear on focusable elements.
Mix and match different trigger types for flexible interactions.
Fine-tune scroll behavior with advanced options.
Choose your preferred installation method.
npm install modus-underline-js
yarn add modus-underline-js
pnpm add modus-underline-js
<!-- CSS -->
<link rel="stylesheet" href="https://unpkg.com/modus-underline-js@latest/dist/underline.css">
<!-- JavaScript -->
<script src="https://unpkg.com/modus-underline-js@latest/dist/underline.js"></script>
import { initRandomUnderlines } from 'modus-underline-js';
import 'modus-underline-js/dist/underline.css';
initRandomUnderlines();
Copy and paste these examples to get started quickly.
<!-- Include CSS and JS -->
<link rel="stylesheet" href="modus-underline-js/dist/underline.css">
<script src="modus-underline-js/dist/underline.js"></script>
<!-- That's it! SVG container is auto-generated -->
<h1>
True <b data-draw-line>creativity</b> thrives when
<b data-draw-line>expression</b> guides the vision.
</h1>
<h1>
<b data-draw-line data-triggers="load,hover" data-load-delay="0">First</b> appears immediately,
<b data-draw-line data-triggers="load,hover" data-load-delay="300">second</b> after 300ms,
<b data-draw-line data-triggers="load,hover" data-load-delay="600">third</b> after 600ms.
</h1>
<p>
These words animate on scroll: <b data-draw-line data-triggers="scroll" data-scroll-delay="0">first</b>,
<b data-draw-line data-triggers="scroll" data-scroll-delay="150">second</b>,
<b data-draw-line data-triggers="scroll" data-scroll-delay="300">third</b>.
</p>
<b data-draw-line data-triggers="hover,click,scroll">
Responds to hover, click, and scroll
</b>
<!-- Instant appearance (no animation) -->
<b data-draw-line data-triggers="scroll" data-scroll-animate="false">instant</b>
<!-- Clear when leaving viewport -->
<b data-draw-line data-triggers="scroll" data-scroll-clear="true">clears on scroll out</b>
<button id="trigger-btn">Trigger Underline</button>
<p>This word will be <b data-draw-line id="target-word">underlined</b> when clicked.</p>
<script>
document.getElementById('trigger-btn').addEventListener('click', () => {
ModusUnderline.triggerUnderline('#target-word');
});
</script>
<script type="module">
import { initRandomUnderlines } from 'modus-underline-js';
// Custom configuration
initRandomUnderlines({
svgPath: '/custom/underlines.svg', // Optional: use custom SVG
containerSelector: '.my-container' // Optional: custom container
});
</script>
:root {
--underline-speed: 0.24s; /* Animation speed */
--underline-offset: 12px; /* Distance from text */
}
/* Custom underline color */
.underline-svg path {
stroke: #ff6b6b; /* Custom color */
stroke-width: 8; /* Thinner line */
}