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

target-highlight

v0.10.0

Published

Highlight DOM elements by overlaying the rest of the page

Downloads

93

Readme

target-highlight

npm GitHub issues License npm

A lightweight, zero‑dependency JavaScript library to spotlight DOM elements with a customizable overlay, border, padding, and optional tooltip. Single or multiple elements can be highlighted, using usual selectors.

DEMO

target-highlight can be used for example to setup a tutorial by highlighting elements.

Features

  • Overlay the page, carving out “holes” around target elements
  • Customizable overlay color, border color, width, radius, padding
  • Tooltip support (single or per‑element) with automatic positioning
  • Configurable via options or global defaults

Installation

npm install target-highlight
# or
yarn add target-highlight

Usage

import {
  targetHighlight,
  targetHide,
  defaultConfig,
  HighlightOptions,
} from "target-highlight";

// Define options
const options = {
  overlayColor: "#00000080", // all color formats will work
  borderColor: "red", // all color formats will work
  singleTooltip: true,
  padding: "2px", // same as css
  borderRadius: 2,
  overlayZIndex: 2,
  hidePointerEvents: false,
  scrollToTarget: {
    // Use the same options as the native scrollIntoView api
    behavior: "smooth",
    block: "center",
    inline: "center",
  },
  nextCallback: () => {}, // use your callback when clicking on a button with an id of target-highlight-button-previous
  previousCallback: () => {}, // use your callback when clicking on a button with an id of target-highlight-button-previous
  stopCallback: () => {}, // use your callback when clicking on a button with an id of target-highlight-button-stop
  tooltip: "My content", // can also be a callback returning html content
  forceTooltipPosition: null, // 'top' | 'right' | 'bottom' | 'left' | null, default: null
  useResizeObserver: true, // If true, will trigger a re-render when the highlighted element resizes
  blockedKeys: [], // Add keyboard keys that will be inactive when the application is running
};

// Target an element using any selector

targetHighlight("#myDiv", {
  ...options,
  tooltip: "This is my div",
});

// Or target many elements
targetHighlight(".myClass", options);

// Remove all highlights
targetHide();

Customize the tooltip

Target the following css class to customize the tooltip:

.target-highlight-tooltip {
}

The tooltip can also be passed a callback returning html content:

targetHighlight("#myDiv", {
  ...config,
  tooltip: () => {
    return `
      <div>
        My custom tooltip
      </div>
    `;
  },
});

When highlighting multiple elements, you may need to show individual tooltips on each element. Use the data-target-highlight-tooltip attribute on the highlighted elements to setup the individual tooltip contents. You can also use the data-target-highlight-tooltip-position to force the tooltip position ('top' | 'right' | 'bottom' | 'left'). In this case, you won't need the tooltip option normally passed to targetHighlight. Bear in mind using data attributes, the tooltip content can only be a string.

<div
  class="mySelection"
  data-target-highlight-tooltip="This is div 1"
  data-target-highlight-tooltip-position="bottom"
>
  Some content
</div>
<div
  class="mySelection"
  data-target-highlight-tooltip="This is div 2"
  data-target-highlight-tooltip-position="left"
>
  Some other content
</div>

Defining steps

You can create a scenario to move from step to step. Add data-step="step" on the elements part of the scenario, where step is a number.

// Define step variables
const step = {
  current: 0,
  max: 5,
};

// Define callbacks in options
const options = {
  nextCallback: () => moveStep("next"),
  previousCallback: () => moveStep("previous"),
  stopCallback: targetHide,
};

// Define blocked keys
const blockedKeys = [" ", "Tab"];

// Define a function to call the library and apply event listeners
// In this example, chevron icons are added as plain svg
// Buttons with id #target-highlight-button-previous and #target-highlight-button-next will be recognized by the library, and events attached to them.
function applySteps() {
  targetHighlight(`[data-step="${step.current}"]`, {
    ...options,
    blockedKeys,
    tooltip: () => {
      return `<div style="position:relative; padding: 0 24px">This is step ${step.value}</div><button id="target-highlight-button-previous" style="position: absolute; top: 50%; left: 0; transform: translateY(-50%)">${chevronLeftIcon}</button><button id="target-highlight-button-next" style="position: absolute; top: 50%; right: 0; transform: translateY(-50%)">${chevronRightIcon}</button>`;
    },
  });

  setTimeout(() => {
    applyStepListeners(options);
  }, 10);
}

// Define a function to move through the steps
function moveStep(direction) {
  if (direction === "next") {
    step.current += 1;
    if (step.current > step.max) {
      step.current = 0;
    }
  } else {
    step.current -= 1;
    if (step.current < 0) {
      step.current = step.max;
    }
  }
  applySteps();
}

Ignore elements

Use the data-target-highlight ignore data attribute on elements never to be highlighted:

<!-- When targeting the .selection class, only one element will be highlighted -->
<div class="selection">I will be selected</div>
<div class="selection" data-target-highlight-ignore>I will not be selected</div>

Blocked keys

Combine hidePointerEvents: false with blocked keys, to prevent events outside of the tour. List of all the available blockable keys:

type KeyboardNavigationKey =
  | " "
  | "Tab"
  | "Enter"
  | "ArrowUp"
  | "ArrowDown"
  | "ArrowLeft"
  | "ArrowRight"
  | "Home"
  | "End"
  | "PageUp"
  | "PageDown"
  | "Escape";

Set blocked keys in the options object:

blockedKeys: [
  " ",
  "Tab",
  "Enter",
  "ArrowUp",
  "ArrowDown",
  "ArrowLeft",
  "ArrowRight",
  "Home",
  "End",
  "PageUp",
  "PageDown",
  "Escape",
];

Blocked events will be restored when targetHide is called.

Tooltip transitions

This library does not inject CSS. To enable tooltip transitions, add for example the following to your app’s global styles:

.target-highlight-tooltip {
  opacity: 1;
  transition: opacity 0.3s;
  will-change: opacity;
}

.target-highlight-tooltip.fade-in {
  opacity: 0;
  animation: fadeIn 0.3s forwards;
}

.target-highlight-tooltip.fade-out {
  opacity: 1;
  animation: fadeOut 0.3s forwards;
  pointer-events: none;
}

@keyframes fadeIn {
  to {
    opacity: 1;
  }
}

@keyframes fadeOut {
  to {
    opacity: 0;
  }
}