@nine-slice-frame/vue
Version:
Nine-slice scaling component for Vue 3 using CSS border-image
157 lines (118 loc) ⢠6.31 kB
Markdown
# @nine-slice-frame/vue
[](https://www.npmjs.com/package/@nine-slice-frame/vue)
[](https://opensource.org/licenses/MIT)
Nine-slice scaling component for Vue 3 using CSS `border-image`.
šÆ **[Live Demo & Tester Tool](https://callum-gander.github.io/nine-slice-frame/)**
## 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 Vue. This package only requires Vue 3 as a peer dependency.
**Incredibly Small** - Minimal bundle impact: **1.33KB / 0.67KB 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 all frameworks:
- [@nine-slice-frame/react](https://www.npmjs.com/package/@nine-slice-frame/react)
- [@nine-slice-frame/vue](https://www.npmjs.com/package/@nine-slice-frame/vue) (you are here)
- [@nine-slice-frame/svelte](https://www.npmjs.com/package/@nine-slice-frame/svelte)
- [@nine-slice-frame/solid](https://www.npmjs.com/package/@nine-slice-frame/solid)
## Installation
```bash
npm install @nine-slice-frame/vue
# or
pnpm add @nine-slice-frame/vue
# or
yarn add @nine-slice-frame/vue
```
## Usage
```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>
```
## Props
| Prop | Type | Default | Description |
| ------------- | --------------------------------------------- | ----------- | --------------------------------------------------------------------------------- |
| `image-path` | `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 |
| `border-width`| `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 |
| `class` | `string` | `''` | Additional CSS class names |
| `style` | `StyleValue` | `{}` | Additional inline styles |
**Note:** Vue uses kebab-case for props in templates (`image-path`, `border-width`).
## Advanced Usage
### Different Slice Values Per Edge
```vue
<template>
<NineSliceFrame
image-path="/ui/fancy-frame.png"
:slice="{ top: 10, right: 8, bottom: 10, left: 8 }"
:border-width="6"
>
Content with asymmetric border
</NineSliceFrame>
</template>
```
### Custom Styling
```vue
<template>
<NineSliceFrame
image-path="/ui/frame.png"
:slice="8"
:border-width="10"
class="my-custom-frame"
:style="{ padding: '20px', minHeight: '200px' }"
>
Styled content
</NineSliceFrame>
</template>
```
## TypeScript
This package includes TypeScript definitions out of the box.
## Requirements
- Vue >= 3.3.0
## License
MIT Ā© Callum Gander
## Links
- [Main Repository](https://github.com/callum-gander/nine-slice-frame)
- [Live Demo](https://callum-gander.github.io/nine-slice-frame/)
- [Report Issues](https://github.com/callum-gander/nine-slice-frame/issues)