npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

readmore-lines

v1.0.0

Published

A lightweight JavaScript library for creating 'read more/read less' functionality with text truncation

Readme

ReadMore.js

A lightweight, high-performance JavaScript library for creating "read more/read less" functionality with text truncation. Features automatic caching, smooth animations, and comprehensive browser support.

Features

  • 🚀 High Performance: Cached line height calculations and CSS styles
  • 🧠 Smart Caching: Automatic memory management with WeakMap
  • 📱 Responsive: Works with any text content and container size
  • Accessible: ARIA attributes, keyboard navigation, and semantic HTML
  • 🎨 Customizable: Flexible styling and configuration options
  • 📦 Lightweight: No external dependencies, ~3KB minified

Installation

npm

npm install readmore-lines

yarn

yarn add readmore-lines

CDN

<!-- Development version (unminified) -->
<script src="https://unpkg.com/readmore-lines@latest/dist/readmore.js"></script>

<!-- Production version (minified) -->
<script src="https://unpkg.com/readmore-lines@latest/dist/readmore.min.js"></script>

UMD usage (script tag)

When using the UMD build via a script tag, the global is a callable function. Call it as readmore(...):

<div id="my-text">Long content here...</div>
<script src="./dist/readmore.js"></script>
<script>
  readmore({ targetElement: document.getElementById('my-text'), linesLimit: 4 });
  // Utilities are available on the same namespace:
  // readmore.destroyReadMore(...)
</script>

Quick Start

Basic Usage

import readmore from 'readmore-lines';

// Simple implementation
readmore({
    targetElement: document.getElementById('my-text')
});

API Reference

readmore(options)

The main function that implements the read more/less functionality.

Parameters

| Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | targetElement | HTMLElement | ✅ | - | The DOM element to apply readmore functionality to | | readMoreLabel | string | ❌ | 'Read more...' | Text for the "read more" link | | readLessLabel | string | ❌ | 'Read less' | Text for the "read less" link | | targetClass | string | ❌ | 'read-more-target' | CSS class applied to the target element | | linkClass | string | ❌ | 'read-more-link' | CSS class applied to the toggle link | | linesLimit | number | ❌ | 8 | Maximum number of lines before truncating |

Example

readmore({
    targetElement: document.getElementById('article-content'),
    readMoreLabel: 'Continue reading...',
    readLessLabel: 'Show less',
    linesLimit: 5,
    targetClass: 'article-truncate',
    linkClass: 'read-more-button'
});

Styling

Default Styles

The library automatically adds CSS for text truncation:

.read-more-target {
    display: -webkit-box;
    overflow: hidden;
    text-overflow: ellipsis;
    -webkit-line-clamp: 8; /* or your specified linesLimit */
    -webkit-box-orient: vertical;
}

Custom Styling

You can customize the appearance by targeting the generated classes:

.read-more-target {
    /* Your custom truncation styles */
}

.read-more-link {
    color: #007bff;
    text-decoration: none;
    font-weight: bold;
}

.read-more-link:hover {
    text-decoration: underline;
}

Accessibility Features

ARIA Support

  • aria-expanded: Automatically updates to reflect content state
  • aria-controls: Links button to controlled content
  • role="button": Proper semantic role for screen readers

Keyboard Navigation

  • Enter key: Activates the toggle functionality
  • Space key: Activates the toggle functionality
  • Tab navigation: Button is focusable and follows tab order

Semantic HTML

  • Uses <button> element instead of <a> for better semantics
  • Automatically assigns unique IDs for proper ARIA relationships
  • Maintains focus management during interactions

Browser Support

  • Chrome 6+
  • Firefox 3.6+
  • Safari 5+
  • Edge 12+
  • IE 9+ (with polyfills for WeakMap)

Build Outputs

The library provides multiple build formats for different use cases:

| File | Size | Description | |------|------|-------------| | readmore.js | ~11KB | Development version (unminified, with sourcemap) | | readmore.min.js | ~2.5KB | Production version (minified, optimized) | | readmore.esm.js | ~10KB | ES Module version |

File Size Comparison

  • Unminified: ~11KB (readable, with comments)
  • Minified: ~2.5KB (77% size reduction)
  • Gzipped: ~1.2KB (estimated)

Performance

Caching System

  • CSS Caching: Prevents duplicate style additions
  • Line Height Caching: Caches computed line heights per element
  • Memory Management: Uses WeakMap for automatic garbage collection

Optimization Features

  • Efficient line height calculations
  • Minimal DOM queries
  • Automatic cache invalidation

Examples

Multiple Elements

// Apply to multiple elements efficiently
document.querySelectorAll('.truncate').forEach(element => {
    readmore({
        targetElement: element,
        linesLimit: 3
    });
});

Custom Styling

<style>
.my-custom-truncate {
    background: linear-gradient(to bottom, transparent 0%, white 100%);
}

.my-custom-link {
    background: #007bff;
    color: white;
    padding: 5px 10px;
    border-radius: 3px;
    text-decoration: none;
}
</style>

<script>
readmore({
    targetElement: document.getElementById('content'),
    targetClass: 'my-custom-truncate',
    linkClass: 'my-custom-link',
    readMoreLabel: 'Read Full Article',
    readLessLabel: 'Collapse'
});
</script>

Cleanup and Instance Management

import readmore, { 
    destroyReadMore, 
    hasReadMoreInstance, 
    getReadMoreInstance,
} from 'readmore-lines';

// Check if element has readmore functionality
if (hasReadMoreInstance(element)) {
    console.log('Element has readmore functionality');
}

// Get the instance for advanced control
const instance = getReadMoreInstance(element);
if (instance) {
    console.log('Instance configuration:', instance.config);
}

// Destroy readmore functionality and clean up resources
destroyReadMore(element);

// Clear all CSS cache (useful for complete reset)
clearReadMoreCache();

Dynamic Content Management

// Handle dynamic content updates
function updateContent(element, newContent) {
    // Destroy existing readmore if present
    if (hasReadMoreInstance(element)) {
        destroyReadMore(element);
    }
    
    // Update content
    element.innerHTML = newContent;
    
    // Reapply readmore functionality
    readmore({
        targetElement: element,
        linesLimit: 4
    });
}

// Handle style changes that affect line height
function updateElementStyles(element) {
    // Apply new styles
    element.style.fontSize = '18px';
    element.style.lineHeight = '1.5';
    
    // Recalculate if readmore is active
    if (hasReadMoreInstance(element)) {
        const instance = getReadMoreInstance(element);
        // Force recalculation by destroying and recreating
        destroyReadMore(element);
        readmore({
            targetElement: element,
            linesLimit: instance.config.linesLimit
        });
    }
}

Development

Building

# Install dependencies
npm install

# Build all versions (development + production)
npm run build

# Build development version only (unminified)
npm run build:dev

# Build production version only (minified)
npm run build:prod

# Run tests
npm test

# Lint code
npm run lint

Project Structure

readmore-lines/
├── src/
│   ├── readmore.js      # Main library file
│   └── readmore.d.ts    # TypeScript declarations
├── dist/                # Built files
│   ├── readmore.js      # Development build (unminified)
│   ├── readmore.min.js  # Production build (minified)
│   ├── readmore.esm.js  # ES Module build
│   └── *.map            # Source maps
├── tests/               # Test files
├── package.json
├── rollup.config.js
└── README.md

Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

This project is licensed under the MIT License - see the LICENSE file for details.

Changelog

v1.0.0

  • Initial release
  • Core readmore functionality
  • CSS and line height caching
  • TypeScript support
  • Comprehensive documentation

Support

If you encounter any issues or have questions, please file an issue on GitHub.


Made with ❤️ by Konstantin Agafonov