---
title: "OutlineBorder"
description: "A wrapper that adds an outline with optional clipping."
category: Effects
status: beta
since: 0.3.4
tags: [border, ring, clip, mask]
syncStatus: reviewed
verified: true
---

## Usage

### Outline Modes
Use `ring-offset` for avatar outlines and `border` when the outline should take up layout space.
::::TuffDemoWrapper{demo="OutlineBorderBasicDemo" code-lang="vue"}
---
code: |
  <template>
    <TxOutlineBorder :ring-width="2" ring-color="var(--tx-color-primary)" :offset="2">
      <div class="avatar">TX</div>
    </TxOutlineBorder>

    <TxOutlineBorder variant="border" :border-width="2" shape="rect" :border-radius="12">
      <div class="avatar avatar--rect">UI</div>
    </TxOutlineBorder>
  </template>
---
::::

### Mask Clipping
Use `clip-mode="mask"` for shapes that border radius cannot express, such as hexagons.
::::TuffDemoWrapper{demo="OutlineBorderMaskClipDemo" code-lang="vue"}
---
code: |
  <template>
    <TxOutlineBorder
      variant="ring"
      :ring-width="2"
      ring-color="var(--tx-color-primary)"
      clip-mode="mask"
      clip-shape="hexagon"
    >
      <div class="hex-avatar">AI</div>
    </TxOutlineBorder>
  </template>
---
::::

### Best Practices

- Prefer `overflow` for circular or rounded avatars; it is cheaper and easier to debug than `mask`.
- Use `ring-offset` when the outline needs a visible gap from the content.
- Give the slotted content an explicit width and height so masks and rings keep a stable geometry.
- Use `as="span"` only in inline contexts; keep block wrappers for cards, thumbnails, and list media.

## API Reference

### Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `as` | `string` | `'div'` | Root element tag. |
| `variant` | `'border' \| 'ring' \| 'ring-offset' \| 'ring-inset'` | `'ring-offset'` | Outline mode. |
| `shape` | `'circle' \| 'rect' \| 'squircle'` | `'circle'` | Shape; sets the default radius and what `clipShape="auto"` resolves to. |
| `borderRadius` | `string \| number` | - | Explicit radius. |
| `borderWidth` | `string \| number` | `'1px'` | Border width; also the fallback ring width. |
| `borderColor` | `string` | `'var(--tx-border-color)'` | Border color; also the fallback ring color. |
| `borderStyle` | `'solid' \| 'dashed' \| 'dotted'` | `'solid'` | Border style for `variant="border"`. |
| `ringWidth` | `string \| number` | `borderWidth` | Ring width. |
| `ringColor` | `string` | `borderColor` | Ring color. |
| `offset` | `string \| number` | `'2px'` | Gap width for `variant="ring-offset"`. |
| `offsetBg` | `string` | `'var(--tx-bg-color)'` | Color of the gap. |
| `padding` | `string \| number` | `0` | Padding of the inner slot wrapper. |
| `clipMode` | `'none' \| 'overflow' \| 'clipPath' \| 'mask'` | `'overflow'` | Clipping strategy for the content layer. |
| `clipShape` | `'auto' \| 'circle' \| 'rounded' \| 'squircle' \| 'hexagon'` | `'auto'` | Clip shape; `auto` maps `shape` to `circle`, `rounded`, or `squircle`. |

### Slots

| Slot | Props | Description |
|------|-------|-------------|
| `default` | - | Content wrapped by the outline and the clipping layer. |

## Overview

- The component has no intrinsic size; the slotted content sets the box. Numeric size props are treated as px.
- `variant="border"` writes a real CSS border; ring variants use `box-shadow` and don't affect layout size.
- `clipMode`: `overflow` clips through `border-radius`, `clipPath` writes a CSS `clip-path`, and `mask` writes an inline SVG mask (`circle`, `hexagon`, and `squircle` only).
- Under `clipPath`, `rounded` and `squircle` both resolve to `inset(0 round var(--tx-outline-radius))`; the true squircle renders only with `mask`.
- The outline follows only `border-radius` and `clipShape` affects only the content layer, so the outline doesn't trace `hexagon` / `squircle`; use a shaped `drop-shadow` filter when it must.
- It is a visual wrapper only and adds no role, label, or image semantics; keep alt text, focus, and click targets on the slotted content.

## Technologies

- The outline paints on the root and clipping applies to the content layer `.tx-outline-border__content`; both share the radius through `--tx-outline-radius`.
- Source: `packages/tuffex/packages/components/src/outline-border/`.

<TuffDocSourceLink />
