---
title: "GlassSurface"
description: "A glass container that refracts the content behind it."
category: Effects
status: beta
since: 0.3.4
tags: [glass, blur, refraction]
syncStatus: reviewed
verified: true
---

## Usage

### Basic
:::TuffDemoWrapper{demo="GlassSurfaceGlassSurfaceDemo" code-lang="vue"}
---
code: |
  <template>
    <div class="backdrop">
      <TxGlassSurface :width="360" :height="160" :border-radius="20" :background-opacity="0.08">
        GlassSurface
      </TxGlassSurface>
    </div>
  </template>
---
:::

### Parameter Tuning
:::TuffDemoWrapper{demo="GlassSurfaceGlassSurface2Demo" code-lang="vue"}
---
code: |
  <template>
    <TxGlassSurface
      :width="360"
      :height="160"
      :blur="blur"
      :displace="displace"
      :distortion-scale="distortionScale"
    >
      GlassSurface
    </TxGlassSurface>
    <TxSlider v-model="blur" :min="0" :max="24" />
    <TxSlider v-model="displace" :min="0" :max="6" :step="0.1" />
    <TxSlider v-model="distortionScale" :min="-600" :max="0" :step="10" />
  </template>
---
:::

### Best Practices

- Use it only where artwork, images, or gradients benefit from refraction; use `TxBaseSurface` or `TxCard` for regular cards.
- Set `width`, `height`, and `borderRadius` explicitly when the glass sits over scrolling content or images.
- Tune `blur`, `backgroundOpacity`, and `saturation` against the real background so text behind stays readable.
- Reserve large `distortionScale` values and wide channel offsets for hero or preview surfaces, not dense forms.
- Put important controls in the default slot.

## API Reference

### Props

::TuffPropsTable
---
rows:
  - name: width
    type: "string | number"
    default: "'200px'"
    description: Surface width; numbers are px, strings are used as-is.
  - name: height
    type: "string | number"
    default: "'200px'"
    description: Surface height; numbers are px, strings are used as-is.
  - name: borderRadius
    type: number
    default: 20
    description: Outer radius in px, also used by the displacement map.
  - name: borderWidth
    type: number
    default: 0.07
    description: Edge-size multiplier of the displacement map mask.
  - name: brightness
    type: number
    default: 70
    description: Lightness percentage of the map's inner mask.
  - name: opacity
    type: number
    default: 0.93
    description: Alpha of the map's inner mask.
  - name: blur
    type: number
    default: 11
    description: Blur radius of the map mask; also the blur of the backdrop-filter fallback.
  - name: displace
    type: number
    default: 0.5
    description: Final blur (feGaussianBlur.stdDeviation) after the RGB maps are blended.
  - name: backgroundOpacity
    type: number
    default: 0
    description: Background alpha on the SVG-filter path.
  - name: saturation
    type: number
    default: 1
    description: Saturation on the SVG-filter path.
  - name: distortionScale
    type: number
    default: -180
    description: Base displacement scale of the red, green, and blue maps.
  - name: redOffset
    type: number
    default: 0
    description: Red offset added to distortionScale.
  - name: greenOffset
    type: number
    default: 10
    description: Green offset added to distortionScale.
  - name: blueOffset
    type: number
    default: 20
    description: Blue offset added to distortionScale.
  - name: xChannel
    type: "'R' | 'G' | 'B'"
    default: "'R'"
    description: X-axis channel read by all three maps.
  - name: yChannel
    type: "'R' | 'G' | 'B'"
    default: "'G'"
    description: Y-axis channel read by all three maps.
  - name: mixBlendMode
    type: "'normal' | 'multiply' | 'screen' | 'overlay' | 'darken' | 'lighten' | 'color-dodge' | 'color-burn' | 'hard-light' | 'soft-light' | 'difference' | 'exclusion' | 'hue' | 'saturation' | 'color' | 'luminosity' | 'plus-darker' | 'plus-lighter'"
    default: "'difference'"
    description: Blend mode of the blue gradient when the map is generated.
---
::

### Slots

| Slot | Props | Description |
|------|-------|-------------|
| `default` | - | Panel content, centered in `.tx-glass-surface__content` above the filter layer. |

## Overview

- The rendering path follows support: SVG displacement refraction with `backdrop-filter: url()`, else a `blur()` frosted backdrop, else a translucent background with a border.
- Safari, Firefox, SSR, and environments without `CSS.supports` skip refraction; the fallbacks keep size, radius, and readability but drop RGB refraction.
- The displacement map is built from the measured size and regenerated when the size or an optical prop changes.
- The generated SVG is decorative, non-interactive, and sits below the content layer.

## Technologies

- Three `feDisplacementMap` passes shift the red, green, and blue channels separately and recombine them into a chromatic refraction.
- Source: `packages/tuffex/packages/components/src/glass-surface/`.

<TuffDocSourceLink />
