JavaScript Box Shadow Parser


By HTML Code Generator Source on GitHub

Reading CSS box-shadow values in JavaScript can be complex because they combine offsets, blur, spread, colors, and optional inset values. JavaScript Box Shadow Parser converts any box-shadow value into structured layer objects and can also convert those objects back into valid CSS with stringify().

Built for real-world CSS, it supports multiple shadow layers, rgba(), hsl(), modern color syntax, hex colors, named colors, and inset values. With zero dependencies and TypeScript support, it integrates easily into shadow generators, design tools, style editors, and CSS-to-JavaScript workflows in both browsers and Node.js.

What is JavaScript Box Shadow Parser?

JavaScript Box Shadow Parser is a zero-dependency library that converts CSS box-shadow values into structured JavaScript layer objects - and back again with stringify(). It supports multi-layer shadows, every CSS color format, and the inset keyword, and runs in both the browser and Node.js.

Features

css-box-shadow-parser Features

  • Multi-layer parsing - splits comma-separated shadows into one object per layer.
  • Full declaration support - accepts raw values or complete box-shadow: ...; declarations and strips the property name and semicolon automatically.
  • All color formats - 3/4/6/8-digit hex, rgb(), rgba(), hsl(), hsla(), named colors, transparent, and currentcolor.
  • Modern and legacy syntax - handles both comma syntax and the space/slash syntax such as rgb(0 0 0 / 0.5) and hsl(270 80% 50% / 0.6).
  • Smart comma splitting - commas inside color functions are never mistaken for layer separators.
  • Resolved hex + alpha - every layer returns a normalized 6-digit hex plus a separate alpha value from 0 to 1.
  • Inset detection - recognizes the inset keyword wherever it appears in the value.
  • Negative offsets and spread - parses negative x, y, and spread values correctly.
  • Graceful handling - CSS-wide keywords like none, initial, and inherit return an empty array.
  • Zero dependencies - small UMD bundle that works in the browser and Node.js.

Demo

Pick a shadow type from the dropdown to see it parsed in real time. The selected CSS box-shadow value is passed to parse() and the resulting layer objects are shown below, along with a live preview box.

Add box shadow code:

Parsed output:

JSON
[
  {
    "inset": false,
    "x": 4,
    "y": 4,
    "blur": 10,
    "spread": 0,
    "color": "rgba(0,0,0,0.4)",
    "alpha": 0.4,
    "hex": "#000000"
  }
]

Got the parsed objects? Click Back to CSS to run them through stringify() - the inverse of parse() - and rebuild a valid box-shadow string. This is the full round-trip: read a shadow, edit the values, and write it straight back to CSS.

CSS
box-shadow: 4px 4px 10px rgba(0,0,0,0.4);

Browse the source code on GitHub or grab the package from npm.

Install

Install the package from npm for use in Node.js or any bundler, or drop in the script from a CDN to use it directly in the browser with no build step.

NPM

NPM
npm install css-box-shadow-parser

Browser Usage

HTML
<script src="https://unpkg.com/css-box-shadow-parser"></script>

<script>
const layers = BoxShadowParser.parse('4px 4px 10px rgba(0,0,0,0.4)');
console.log(layers);

// output
// [{"inset":false,"x":4,"y":4,"blur":10,"spread":0,"color":"rgba(0,0,0,0.4)","alpha":0.4,"hex":"#000000"}]
</script>

Node.js Usage

JavaScript
const { parse, parseSingle, split } = require('css-box-shadow-parser');

// Single layer
parse('4px 4px 10px rgba(0,0,0,0.4)');

// Multi-layer
parse('0 1px 2px #0002, 0 4px 8px #0002');

// Full CSS declaration - strips "box-shadow:" and ";" automatically
parse('box-shadow: inset 0 2px 4px rgba(0,0,0,.24);');

// CSS keyword - returns empty array
parse('none'); // []

API

The library exposes three functions: parse() for full values, parseSingle() for one shadow token, and split() for tokenizing without parsing.

parse(shadow) - BoxShadowLayer[]

Parses a full box-shadow value, single or multi-layer. Accepts raw values or complete CSS declarations including the box-shadow: property name and trailing semicolon.

JavaScript
parse('0 2px 8px rgba(0,0,0,0.3)')
parse('box-shadow: inset 0 2px 4px rgba(0,0,0,.24);')
parse('0 1px 2px #0002, 0 4px 8px #0002') // multi-layer
parse('none') //  []

parseSingle(token) - BoxShadowLayer | null

Parses a single shadow token. Returns null for invalid or empty input.

JavaScript
parseSingle('inset 0 2px 4px coral')

split(shadow) - string[]

Splits a compound value on top-level commas without parsing. Commas inside rgba(), hsl() and other functions are correctly ignored.

JavaScript
split('4px 4px 0 red, inset 0 0 10px rgba(0,0,0,.5)')
// - ['4px 4px 0 red', 'inset 0 0 10px rgba(0,0,0,.5)']

stringify()

The inverse of parse(). Pass a single layer object or an array of layers and get back a valid CSS box-shadow string. Together, parse() and stringify() let you read a shadow, modify it in code, and write it straight back to CSS.

stringify(input) - string

Accepts a BoxShadowLayer object or an array of them. Numeric offsets are written with px (a value of 0 stays unitless), blur and spread are omitted when not needed, and the original color token is preserved when present - otherwise a color is rebuilt from hex and alpha.

JavaScript
// Round-trip: CSS -> objects -> CSS
const layers = parse('6px 6px 12px #b8b9be, -6px -6px 12px #ffffff');
stringify(layers);
// "6px 6px 12px #b8b9be, -6px -6px 12px #ffffff"

// Edit in between
layers[0].blur = 24;
stringify(layers);
// "6px 6px 24px #b8b9be, -6px -6px 12px #ffffff"

// Build a shadow from a plain object
stringify({ inset: false, x: 0, y: 8, blur: 24, spread: 0, hex: '#6c63ff', alpha: 0.4 });
// "0 8px 24px rgba(108, 99, 255, 0.4)"

// Single object also works
stringify({ inset: true, x: 2, y: 2, blur: 4, spread: 0, color: 'red' });
// "inset 2px 2px 4px red"

Return Type

Each parsed layer is a plain object with the following shape. Offsets, blur, and spread are returned as numbers, color keeps the original token, and hex plus alpha give you a normalized color you can use anywhere.

Property Type Description
inset boolean true if the shadow uses inset
x number Horizontal offset in px
y number Vertical offset in px
blur number Blur radius in px
spread number Spread radius in px (can be negative)
color string Original CSS color token
alpha number Opacity 0–1 (extracted from color)
hex string Resolved 6-digit hex (e.g. #663399)

TypeScript Definitions

The package ships with built-in TypeScript definitions (index.d.ts), so you get full autocomplete and type checking with no @types install required.

JavaScript
import { parse, stringify, BoxShadowLayer } from 'css-box-shadow-parser';

const layers: BoxShadowLayer[] = parse('0 8px 24px rgba(0,0,0,0.4)');

const first: BoxShadowLayer = layers[0];
first.blur;   // number
first.hex;    // string
first.inset;  // boolean

const css: string = stringify(layers);

The exported BoxShadowLayer interface describes every field returned by parse() and parseSingle().

Examples

The examples below show the parsed output for common shadow patterns, from named colors and hex with alpha to inset and multi-layer shadows.

Named color

JavaScript
parse('0 0 28px 6px rebeccapurple')
// [{
//   inset: false, x: 0, y: 0, blur: 28, spread: 6,
//   color: 'rebeccapurple', alpha: 1, hex: '#663399'
// }]

8-digit hex with alpha

JavaScript
parse('0 8px 24px #00000066')
// [{
//   inset: false, x: 0, y: 8, blur: 24, spread: 0,
//   color: '#00000066', alpha: 0.4, hex: '#000000'
// }]

HSL color

JavaScript
parse('0 6px 20px hsl(270 80% 50% / 0.6)')
// [{
//   inset: false, x: 0, y: 6, blur: 20, spread: 0,
//   color: 'hsl(270 80% 50% / 0.6)', alpha: 0.6, hex: '#8019e6'
// }]

Inset shadow

JavaScript
parse('inset 0 2px 4px rgba(0,0,0,0.24)')
// [{
//   inset: true, x: 0, y: 2, blur: 4, spread: 0,
//   color: 'rgba(0,0,0,0.24)', alpha: 0.24, hex: '#000000'
// }]

Multi-layer (neumorphic)

JavaScript
parse('6px 6px 12px #b8b9be, -6px -6px 12px #ffffff')
// [
//   { inset: false, x:  6, y:  6, blur: 12, spread: 0, color: '#b8b9be', alpha: 1, hex: '#b8b9be' },
//   { inset: false, x: -6, y: -6, blur: 12, spread: 0, color: '#ffffff', alpha: 1, hex: '#ffffff' }
// ]

Split without parsing

JavaScript
split('4px 4px 0 red, inset 0 0 10px rgba(0,0,0,.5)')
// ['4px 4px 0 red', 'inset 0 0 10px rgba(0,0,0,.5)']

Supported Color Formats

Every color format allowed in a CSS box-shadow is recognized and resolved to a hex value with a separate alpha channel.

Format Example
3-digit hex#f00
4-digit hex + alpha#f00a
6-digit hex#ff0000
8-digit hex + alpha#ff000066
rgb() commargb(255, 0, 0)
rgb() space syntaxrgb(255 0 0)
rgba() comma + alphargba(0, 0, 0, 0.5)
rgba() space / slash alphargba(0 0 0 / 0.5)
hsl() commahsl(270, 80%, 50%)
hsl() space + slash alphahsl(270 80% 50% / 0.6)
hsl() deg unithsl(200deg 70% 50%)
hsla() comma + alphahsla(340, 82%, 52%, 0.7)
Named colorrebeccapurple, coral, etc.
transparentalpha=0
currentcolorresolves to #000000

Use Cases

Anywhere you need to read, edit, or transform shadows programmatically:

  • Shadow editors and generators - parse a pasted value into sliders and color pickers, then stringify() the result back to CSS.
  • Design-token and theme tools - convert shadow declarations into JSON tokens for design systems.
  • CSS-to-JS pipelines - feed shadow data into canvas, SVG, or React Native styling, which use separate shadow properties.
  • Linters and visual diff tools - compare two shadows layer by layer instead of as raw strings.
  • Color extraction - pull resolved hex and alpha values out of any shadow for previews or contrast checks.
  • Migration scripts - normalize inconsistent shadow syntax across a large codebase.

Browser & Environment Support

The library is plain ES5-compatible JavaScript in a UMD wrapper, so it runs anywhere with no build step.

EnvironmentSupport
Chrome, Firefox, Safari, EdgeAll modern versions
Node.js14 and above
Module systemsCommonJS, browser global, CDN script tag
TypeScriptBuilt-in type definitions
DependenciesNone

Frequently Asked Questions (FAQ)

How do I parse a CSS box-shadow string in JavaScript?

Pass the value to parse(): BoxShadowParser.parse('4px 4px 10px rgba(0,0,0,0.4)'). It returns an array of layer objects, each with inset, x, y, blur, spread, color, alpha, and a resolved hex value. You can pass a raw value or a full box-shadow: ...; declaration.

Does it support multiple shadow layers?

Yes. Comma-separated shadows are split into one object per layer, and commas inside rgba() or hsl() functions are correctly ignored, so multi-layer values parse reliably.

What color formats are supported?

3-, 4-, 6-, and 8-digit hex, rgb(), rgba(), hsl(), hsla() in both comma and space/slash syntax, all named CSS colors, transparent, and currentcolor. Every color resolves to a 6-digit hex plus a separate alpha value.

Does it work in Node.js and the browser?

Yes. The library uses a UMD wrapper, so it works as a CommonJS module in Node.js (require('css-box-shadow-parser')) and as a global BoxShadowParser in the browser via a script tag or CDN.

Does the parser have any dependencies?

No. It is a zero-dependency library released under the MIT license, so you can use it freely in personal and commercial projects.

What happens with keywords like none or inherit?

CSS-wide keywords such as none, initial, inherit, and unset return an empty array, so you can safely call parse() on any computed style value.

License

Released under the MIT License - free to use in personal and commercial projects. See the LICENSE file on GitHub for full terms.