nine-slice-frame Svelte Themes

Nine Slice Frame

A modern nine-slice scaling component for React, Vue, Svelte, and Solid. Zero dependencies, tiny bundle sizes (~1KB), and native CSS performance. Perfect for scalable UI frames, borders, and pixel art interfaces.

nine-slice-frame

Modern nine-slice scaling components for React, Vue, Svelte, and Solid using CSS border-image.

šŸŽÆ Live Demo & Tester Tool

What is Nine-Slice Scaling?

Nine-slice scaling divides an image into 9 sections, allowing it to scale to any size while preserving corner details and preventing distortion. Perfect for UI frames, borders, panels, and buttons that need to scale dynamically.

ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│ Corner  │ Top Edge  │ Corner  │
│ (Fixed) │ (Scale H) │ (Fixed) │
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
│  Left   │  Center   │  Right  │
│  Edge   │ (Scale    │  Edge   │
│(Scale V)│  Both)    │(Scale V)│
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
│ Corner  │ Bottom    │ Corner  │
│ (Fixed) │   Edge    │ (Fixed) │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜

Why Nine-Slice Scaling?

The Problem: Traditional image scaling stretches the entire image uniformly, distorting corners, borders, and decorative elements. This makes UI elements look unprofessional and breaks visual consistency.

The Solution: Nine-slice scaling keeps corners and edges crisp while only stretching the middle sections. This means:

  • Single image, infinite sizes - One asset works for buttons, dialogs, and panels of any dimension
  • Pixel-perfect corners - Ornate borders and rounded corners stay sharp at any scale
  • Smaller file sizes - No need for multiple image variants for different sizes
  • Ideal for pixel art - Preserves the crisp aesthetic of retro-style UIs
  • CSS-native performance - Uses browser-native border-image, no canvas or WebGL overhead

Common Use Cases:

  • Game UI frames and dialog boxes
  • Decorative borders and panels
  • Scalable buttons with ornate edges
  • Retro/pixel art interfaces
  • Dynamic content containers

Why This Library?

Zero Dependencies - No runtime dependencies beyond your framework of choice. Each package only requires its respective framework as a peer dependency.

Incredibly Small - Minimal bundle impact with tiny package sizes:

  • React: ~881B (ESM)
  • Vue: 1.33KB / 0.67KB gzipped
  • Svelte: 1.18KB / 0.62KB gzipped
  • Solid: 3.09KB / 1.28KB gzipped

Native Performance - Uses browser-native CSS border-image property, not canvas rendering or heavy image manipulation libraries. Fast, efficient, and hardware-accelerated.

Framework-Agnostic API - Same simple, consistent API across React, Vue, Svelte, and Solid. Learn once, use everywhere.

Installation

React

npm install @nine-slice-frame/react
# or
pnpm add @nine-slice-frame/react
# or
yarn add @nine-slice-frame/react

Vue

npm install @nine-slice-frame/vue
# or
pnpm add @nine-slice-frame/vue
# or
yarn add @nine-slice-frame/vue

Svelte

npm install @nine-slice-frame/svelte
# or
pnpm add @nine-slice-frame/svelte
# or
yarn add @nine-slice-frame/svelte

Solid

npm install @nine-slice-frame/solid
# or
pnpm add @nine-slice-frame/solid
# or
yarn add @nine-slice-frame/solid

Usage

React

import { NineSliceFrame } from '@nine-slice-frame/react';

function App() {
  return (
    <NineSliceFrame
      imagePath="/ui/frame.png"
      slice={7}
      borderWidth={5}
      repeat="stretch"
      fill={true}
      pixelated={true}
    >
      <p>Your content here</p>
    </NineSliceFrame>
  );
}

Vue

<script setup lang="ts">
import { NineSliceFrame } from '@nine-slice-frame/vue';
</script>

<template>
  <NineSliceFrame
    image-path="/ui/frame.png"
    :slice="7"
    :border-width="5"
    repeat="stretch"
    :fill="true"
    :pixelated="true"
  >
    <p>Your content here</p>
  </NineSliceFrame>
</template>

Svelte

<script lang="ts">
  import { NineSliceFrame } from '@nine-slice-frame/svelte';
</script>

<NineSliceFrame
  imagePath="/ui/frame.png"
  slice={7}
  borderWidth={5}
  repeat="stretch"
  fill={true}
  pixelated={true}
>
  <p>Your content here</p>
</NineSliceFrame>

Solid

import { NineSliceFrame } from '@nine-slice-frame/solid';

function App() {
  return (
    <NineSliceFrame
      imagePath="/ui/frame.png"
      slice={7}
      borderWidth={5}
      repeat="stretch"
      fill={true}
      pixelated={true}
    >
      <p>Your content here</p>
    </NineSliceFrame>
  );
}

Props

Prop Type Default Description
imagePath string required Path to the image (relative to public folder)
slice number | object 8 Slice values - number for uniform, or { top, right, bottom, left } for per-edge
borderWidth number 5 Visual border width in pixels
repeat 'stretch' | 'repeat' | 'round' | 'space' 'stretch' Border repeat mode
fill boolean true Use 'fill' to show center of image as background
pixelated boolean true Use pixelated rendering for pixel art
className string '' Additional CSS class names
style React.CSSProperties {} Additional inline styles

Advanced: Different Slice Values Per Edge

<NineSliceFrame
  imagePath="/ui/fancy-frame.png"
  slice={{ top: 10, right: 8, bottom: 10, left: 8 }}
  borderWidth={6}
>
  Content with asymmetric border
</NineSliceFrame>

Development

This is a monorepo managed with pnpm workspaces.

# Install dependencies
pnpm install

# Build all packages
pnpm build

# Build React package only
pnpm build:react

# Run demo site locally
pnpm demo:serve

Roadmap

  • React component
  • Vue component
  • Svelte component
  • Solid component
  • Interactive demo/tester tool

Contributing

Contributions are welcome! Here's how you can help:

  1. Fork the repository and create your branch from main
  2. Make your changes in your forked repository
  3. Test your changes - Run pnpm build and pnpm test to ensure everything works
  4. Submit a pull request with a clear description of your changes

Development Setup

# Clone the repository
git clone https://github.com/callum-gander/nine-slice-frame.git
cd nine-slice-frame

# Install dependencies
pnpm install

# Build all packages
pnpm build

# Run tests
pnpm test

# Type checking
pnpm typecheck

Reporting Issues

Found a bug or have a feature request? Please open an issue with:

  • A clear description of the problem or suggestion
  • Steps to reproduce (for bugs)
  • Expected vs actual behavior
  • Screenshots or code examples if applicable

Resources

License

MIT Ā© Callum Gander

Top categories

Loading Svelte Themes