# Gradual Blur

> Progressive edge blur for headers, footers, captions and carousels, with an optional fade to color that hides at the ends of a scroll.

Gradual Blur softens one edge of a container with stacked backdrop-filter layers. Each layer adds only the blur that is still missing, so the ramp has no visible steps. Fade it into a color, boost the color behind it, clear it on hover, or let it hide itself when a scroll reaches that edge. Scroll the feed, switch scenes and presets in the panel.

<demo-gradual-blur>



</demo-gradual-blur>

## Installation

```bash
npx shadcn-vue@latest add "https://nxui.geoql.in/r/gradual-blur.json"
```

## Usage

Place it inside a positioned parent. With `auto-hide`, it watches a scrollable sibling (or the parent) and fades out at the end of the scroll.

```vue
<script setup lang="ts">
  import GradualBlur from '~/components/ui/gradual-blur/GradualBlur.vue';
</script>

<template>
  <div class="relative h-125 overflow-hidden">
    <div class="h-full overflow-y-auto">
      <!-- long scrolling content -->
    </div>
    <GradualBlur position="top" tint="rgba(18, 15, 23, 0.6)" auto-hide />
    <GradualBlur position="bottom" tint="rgba(18, 15, 23, 0.6)" auto-hide />
  </div>
</template>
```

## Props

<table>
<thead>
  <tr>
    <th>
      Prop
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Default
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        position
      </code>
    </td>
    
    <td>
      <code>
        'top' | 'bottom' | 'left' | 'right'
      </code>
    </td>
    
    <td>
      <code>
        'bottom'
      </code>
    </td>
    
    <td>
      Edge the blur grows toward.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        target
      </code>
    </td>
    
    <td>
      <code>
        'parent' | 'page'
      </code>
    </td>
    
    <td>
      <code>
        'parent'
      </code>
    </td>
    
    <td>
      Sit inside the nearest positioned parent, or stay fixed to the edge of the viewport.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        height
      </code>
    </td>
    
    <td>
      <code>
        string | number
      </code>
    </td>
    
    <td>
      <code>
        '6rem'
      </code>
    </td>
    
    <td>
      How far the blur reaches in from the edge. For left and right this is its width. Numbers are px.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        width
      </code>
    </td>
    
    <td>
      <code>
        string | number
      </code>
    </td>
    
    <td>
      <code>
        -
      </code>
    </td>
    
    <td>
      For top and bottom, a narrower centered band. For left and right, overrides height.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        strength
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        2
      </code>
    </td>
    
    <td>
      How blurry the very edge gets. Each step adds about 12px of blur.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        layers
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        8
      </code>
    </td>
    
    <td>
      Blur layers across the ramp, 1 to 16. More layers give a smoother falloff, fewer show steps.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        curve
      </code>
    </td>
    
    <td>
      <code>
        'linear' | 'bezier' | 'ease-in' | 'ease-out' | 'ease-in-out'
      </code>
    </td>
    
    <td>
      <code>
        'linear'
      </code>
    </td>
    
    <td>
      How the blur builds across the ramp. <code>
        bezier
      </code>
      
       is a smooth S-curve.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        exponential
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Doubles the blur toward the edge so it starts gently. Turn off for an even ramp.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        opacity
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Opacity of the blur layers. Lower values let the sharp content show through.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        saturation
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Color boost of the blurred content, building toward the edge, for a glassy look.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        tint
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        'transparent'
      </code>
    </td>
    
    <td>
      Color the content fades into at the edge, such as your page background. Use rgba for a lighter wash.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        auto-hide
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        false
      </code>
    </td>
    
    <td>
      Fades the blur out when the scroll container reaches this edge.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        container
      </code>
    </td>
    
    <td>
      <code>
        string | HTMLElement | null
      </code>
    </td>
    
    <td>
      <code>
        null
      </code>
    </td>
    
    <td>
      Scroll container watched by <code>
        auto-hide
      </code>
      
      . Defaults to a scrollable sibling, the parent, or the page.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        hover-intensity
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Multiplies the blur while the cursor is over it. 0 clears it on hover, 2 doubles it.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        duration
      </code>
    </td>
    
    <td>
      <code>
        number | string
      </code>
    </td>
    
    <td>
      <code>
        0.3
      </code>
    </td>
    
    <td>
      Length of the hover and auto-hide transitions, in seconds or as a CSS time.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        easing
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        'ease-out'
      </code>
    </td>
    
    <td>
      CSS easing of those transitions.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        z-index
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1000
      </code>
    </td>
    
    <td>
      Stacking order of the overlay.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        class
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        ''
      </code>
    </td>
    
    <td>
      Extra classes for the overlay.
    </td>
  </tr>
</tbody>
</table>

## Accessibility

- The overlay is decorative (`aria-hidden="true"`) and uses `pointer-events: none`, so content under it stays clickable and selectable.
- Hover detection reads pointer position on the window, so it never steals events from the content below.
- Blur and tint are CSS only; there is no animation loop.
- Ported from [React Bits](https://reactbits.dev/animations/gradual-blur) by David Haz.
