How Vue Color Avatar's z-index Layering System Manages Component Order

Vue Color Avatar uses a two-step z-index layering system that combines data-driven widget sorting with CSS stacking to control the visual order of avatar components.

The z-index layering system in the vue-color-avatar repository determines how facial features, accessories, and borders stack to create a cohesive avatar image. This system operates at both the data level—sorting SVG widgets before rendering—and the DOM level—using CSS z-index to separate background, content, and border layers.

Understanding the Two-Step z-index Layering System

The avatar component implements a hybrid approach that separates logical ordering from visual stacking. This ensures that widgets render in the correct sequence while maintaining clean separation between the background, SVG payload, and border elements.

Data-Driven z-index Values

Each widget in an AvatarOption configuration can specify an explicit zIndex property. When omitted, the system falls back to default values defined in src/utils/constant.ts within the AVATAR_LAYER constant.

The default stack assigns specific z-index values to widget types to ensure logical facial composition:

  • Face: 10
  • Eyes: 20
  • Eyebrows: 30
  • Glasses: 90
  • Hair: 80
  • Ears: 102
  • Clothes: 110

This configuration ensures that clothes appear above the body, ears sit properly on the head, and glasses overlay eyes correctly.

Runtime Sorting and SVG Composition

In src/components/VueColorAvatar.vue, the component transforms the widget object into a sorted array before generating the final SVG. The sorting logic (lines 75-80) compares the effective z-index of each widget—either the explicit value or the default from AVATAR_LAYER.

// VueColorAvatar.vue – sorting logic
const sortedList = Object.entries(avatarOption.value.widgets).sort(
  ([, prev], [, next]) => {
    const ix = prev.zIndex ?? AVATAR_LAYER[prev.shape]?.zIndex ?? 0
    const iix = next.zIndex ?? AVATAR_LAYER[next.shape]?.zIndex ?? 0
    return ix - iix
  }
)

Because SVG renders elements in document order, later groups automatically appear above earlier ones. The sorted array ensures that high z-index widgets are appended last, placing them visually on top.

CSS z-index Layering in the DOM

While the data layer manages widget ordering within the SVG, CSS handles the macro-level stacking of the avatar's major components.

The root wrapper (.vue-color-avatar) uses position: relative to establish a stacking context. Three primary layers exist:

  1. Background (Background.vue): Absolutely positioned with no explicit z-index, placing it at the bottom of the stack (lines 16-21).

  2. SVG Payload (.avatar-payload): Assigned z-index: 2 (lines 44-50 in VueColorAvatar.vue), ensuring it renders above the background but below the border.

  3. Border (Border.vue): Absolutely positioned with z-index: 3 (lines 20-25), creating the topmost overlay that frames the entire avatar.

This separation allows the border to consistently frame the avatar regardless of the internal widget configuration, while the background remains firmly behind all facial features.

Practical Examples

Overriding Default Layer Order

To force glasses to appear above hair (useful for certain hairstyles), explicitly set a higher zIndex:

import { AvatarOption } from '@/types'

const customOption: AvatarOption = {
  widgets: {
    face: { shape: 'base', fillColor: '#F9C9B6' },
    hair: { shape: 'pixie', fillColor: '#d2eff3', zIndex: 80 },
    glasses: { shape: 'round', zIndex: 200 }, // Forces glasses to front
    clothes: { shape: 'hoodie', fillColor: '#6c8cff' }
  }
}

Using the Default Stack

For standard avatar generation, omit the zIndex property and rely on the library's internal defaults:

import { getRandomAvatarOption } from '@/utils'

// Generates random avatar using AVATAR_LAYER defaults
<VueColorAvatar :option="getRandomAvatarOption()" />

Inspecting the Rendered Order

To verify the layering system in the browser:

  1. Open DevTools and locate the generated <svg> element
  2. Expand the <g> groups and observe the DOM order
  3. Verify that groups with higher z-index values appear later in the document
  4. Check that the border's z-index: 3 creates the topmost visual layer

Key Implementation Files

File Purpose
src/components/VueColorAvatar.vue Core component implementing widget sorting by z-index and SVG assembly
src/utils/constant.ts Defines AVATAR_LAYER constants providing default z-index values for each widget type
src/components/widgets/Border.vue CSS-based border overlay with z-index: 3
src/components/widgets/Background.vue Background layer positioned behind all other content

Summary

  • Vue Color Avatar implements a two-step z-index layering system combining data-driven sorting with CSS stacking contexts.
  • Widgets receive default z-index values from AVATAR_LAYER in constant.ts, with face at 10, clothes at 110, and ears at 102.
  • The runtime sorting algorithm in VueColorAvatar.vue orders SVG groups by effective z-index before DOM insertion.
  • CSS z-index layers separate the background (implicit), SVG payload (z-index: 2), and border (z-index: 3) into distinct stacking levels.

Frequently Asked Questions

How do I change the layering order of specific avatar widgets?

Override the default stacking by adding a zIndex property to any widget in your AvatarOption configuration. Higher values render above lower ones. For example, setting glasses: { shape: 'round', zIndex: 200 } forces glasses to appear above hair and most other features.

What happens if I don't specify a z-index for a widget?

The system automatically assigns a default value from the AVATAR_LAYER constant defined in src/utils/constant.ts. This ensures consistent rendering across all avatars without requiring manual configuration for every component.

Why does the border appear above all other avatar elements?

The Border.vue component uses CSS z-index: 3 and absolute positioning, placing it in a higher stacking context than the SVG payload (z-index: 2) and the background (no explicit z-index). This guarantees the border frames the entire avatar regardless of internal widget configuration.

Where is the z-index sorting logic implemented?

The sorting algorithm resides in src/components/VueColorAvatar.vue around lines 75-80. It converts the widgets object into an array, calculates the effective z-index for each item (explicit value or default from AVATAR_LAYER), and sorts them in ascending order before SVG generation.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →