Frontend Development 19 min read

Guide Component – Design, Features, and Technical Implementation for Frontend Applications

This article explains the design, presentation modes, precise positioning, keyboard interaction, and technical implementation—including mask handling, popover placement, and React portal usage—of a step‑by‑step guide component for frontend applications, along with code examples and deployment considerations.

ByteFE
ByteFE
ByteFE
Guide Component – Design, Features, and Technical Implementation for Frontend Applications

Component Background

Regardless of whether users are existing or new, when a product releases a new version, launches new features, or updates existing functionality, guidance is required. The guide component acts as a signpost in internet products, leading users through new interfaces, interactions, and functions. Unlike FAQs, product introduction videos, manuals, or UI component help information, the guide integrates with the product UI, appears automatically without requiring user‑triggered actions, and provides a seamless experience.

Images illustrate two typical onboarding components, making the concept of a guide component clear.

Feature Overview

Step‑by‑Step Guide

The Guide component centers on step‑by‑step guidance, acting like a road sign that leads users from a start point to an end point. This mode suits new features with long interaction flows or complex interfaces, allowing users to experience the full operation chain and quickly locate each functional point.

Presentation Modes

Mask Mode

Mask mode uses a semi‑transparent black overlay to dim the product, highlights the target area, and displays a pop‑up window with explanations. This blocks interaction with the rest of the UI, focusing the user’s attention on the highlighted feature.

Popover Mode

When a non‑intrusive experience is desired, the component can render a simple pop‑over window next to the target element without a mask.

Precise Positioning

Initial Positioning

Guide provides twelve alignment options for placing the pop‑over relative to the selected element. Custom horizontal and vertical offsets can be supplied to fine‑tune the position. The following images show top‑left and right‑bottom placements.

The positioning remains accurate when the user zooms or scrolls the page.

Auto‑Scroll

When the next target element is outside the viewport, Guide automatically scrolls the page to bring the element into view before displaying the pop‑over.

Keyboard Interaction

When the guide pop‑over appears, focus is moved to the pop‑over so that screen‑reader users can perceive it. Users can navigate through the pop‑over content using Tab (or Shift+Tab) and dismiss the guide with the Escape key.

The following GIF shows focus moving between elements with the Tab key; when focus reaches the “Next” button, pressing Shift jumps to the next step.

Technical Implementation

Overall Flow

Before displaying a step, the component checks whether it has expired. Expiration is determined by two criteria: a unique key stored in localStorage set to true (indicating the guide has completed) and a props.expireDate prop; if the current time exceeds expireDate , the guide is considered expired and will not render.

If the component is not expired, it renders the steps passed via props.steps . The Step interface is defined as:

interface Step {
    selector: string;
    title: string;
    content: React.Element | string;
    placement: 'top' | 'bottom' | 'left' | 'right' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
    offset: Record<'top' | 'bottom' | 'left' | 'right', number>;
}

const steps = Step[]

For each step, the component finds the highlighted element using step.selector , then positions the pop‑over according to step.placement . After the final step, the unique key in localStorage is set to true so the guide will not show again.

Mask Mode Implementation

The mask is a full‑screen div . To highlight the target element and support rounded corners, the component uses border‑width to create a cut‑out. It reads the target element’s offsetTop , offsetRight , offsetBottom , and offsetLeft , sets those values as the mask’s border‑width , and applies a gray border‑color . A ::after pseudo‑element adds the border‑radius.

Popover Positioning

Guide receives a list of steps, each containing a CSS selector for the anchor element. The component must locate the anchor’s offset parent and place the pop‑over relative to it. The offset parent is the nearest positioned ancestor (or document.documentElement for fixed elements). The algorithm recursively climbs the DOM until it finds an element whose computed style has a non‑default transform , perspective , will‑change , or filter , otherwise it falls back to the document element.

const getContainingBlock = node => {
  let currentNode = getDocument(node).documentElement;
  while (
    isHTMLElement(currentNode) &&
    !['html', 'body'].includes(getNodeName(currentNode))
  ) {
    const css = getComputedStyle(currentNode);
    if (
      css.transform !== 'none' ||
      css.perspective !== 'none' ||
      (css.willChange && css.willChange !== 'auto')
    ) {
      return currentNode;
    }
    currentNode = currentNode.parentNode;
  }
  return currentNode;
};

When the anchor element is positioned fixed , its offsetParent is null . In that case the containing block is typically document.documentElement or the nearest ancestor that establishes a containing block (e.g., has a transform, perspective, etc.).

Mounting the Pop‑over

Because the guide component may be declared in one React component while the target elements reside in others, the pop‑over is rendered using React Portals. The portal renders the pop‑over into the anchor’s offset parent without breaking the React tree.

const Modal = props => (
  ReactDOM.createPortal(
...
,
    offsetParent
  )
);

Offset Calculation

For a placement such as left , the pop‑over is initially aligned to the top‑left corner of the offset parent. The component then adjusts the top offset by offsetTop + h1/2 - h2/2 , where h1 is the anchor’s height and h2 is the pop‑over’s height. Fixed anchors require the pop‑over itself to be positioned fixed so it moves with the viewport.

Arrow Implementation and Positioning

The arrow is a child of the pop‑over, absolutely positioned relative to the pop‑over. Twelve placement options are grouped into two categories: four centered (purple) positions and eight angled (yellow) positions. For centered placements, the arrow is centered on the pop‑over edge, with its opposite side offset by -arrow.diagonalWidth/2 . For angled placements, the arrow’s offset on the side opposite the placement is fixed (e.g., margin ), while the reverse side receives -diagonalWidth/2 .

const placement = 'top' | 'bottom' | 'left' | 'right';
const diagonalWidth = 10;
const style = {
  right: ['bottom', 'top'].includes(placement)
    ? (modal.width - diagonalWidth) / 2
    : '',
  top: ['left', 'right'].includes(placement)
    ? (modal.height - diagonalWidth) / 2
    : '',
  [getReversePosition(placement)]: -diagonalWidth / 2,
};

Hotspot Implementation

The guide also supports a "hotspot" feature, which adds an animated box‑shadow to a div to create a breathing‑light effect. The hotspot’s position is calculated relative to the arrow.

Conclusion

During the early development of Guide, we did not anticipate the breadth of technical challenges required to make such a small component universally applicable. This demonstrates that even tiny UI components demand careful consideration of positioning, scrolling, accessibility, and cross‑context rendering to achieve true generality.

Author: Lilly Jiang & Wind

frontenduiAccessibilityReactpositioningguide componentportals
ByteFE
Written by

ByteFE

Cutting‑edge tech, article sharing, and practical insights from the ByteDance frontend team.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.