Generate smooth, consistent and always-sexy box-shadows, no matter the size, ideal for design token generation.

Overview

smooth-shadow

Generate smooth, consistent and always-sexy box-shadows, no matter the size, ideal for design token generation.

Screenshot of the demo

Demo

As Tobias already pointed out in 2019, a regular singular CSS box-shadow statement is as dull as it gets. Which is fine as long as you use it as a low-level API. And that's what we do by layering multiple box-shadows in a way to make them look a lot more physically realistic. No, the shadows are not really raytraced, but we borrow some concepts.

Many great people tackled the issue from Tobias Sahlin, to Philipp Brumm and Josh W Comeau, but none of them offered their solution as OSS-code. The previous attempts at libraries of other folks give you lots of settings like direct alpha, blur and spread settings, but on the flipside that means and you have to find good values for small and large shadows yourself.

smooth-shadow is largely opinionated in what makes a great smooth shadow and only offers you relevant options for your usecase:

  • Distance (basically the elevation/size of the shadow)
  • Intensity (which should vary depending on environment color)
  • Sharpness (which - although largely opinionated - leaves a little room for the projects style)
  • Color (as real cast shadows pick up the color of reflected light from the surface they are cast on)
  • Light Position (to determine in which direction the shadow should cast)

And as always:

  • zero dependencies
  • fully typed in typescript
  • small footprint (2.3kb minified)
  • CommonJS bundle, .mjs bundle, .d.ts bundle + type-checking & Source maps

Installation

npm i smooth-shadow or yarn add smooth-shadow

Usage

import { getSmoothShadow } from 'smooth-shadow'

// it returns a box-shadow css statement ready to use
const boxShadow = getSmoothShadow()

// eg. on a jsx component
<div style={{ boxShadow }} />

// or eg. in a styled component
styled.div`box-shadow: ${boxShadow}`

// or eg. even better in a styled-component (or any other framework) theme
const cardShadow = getSmoothShadow({ distance: 100 })
const theme = { cardShadow }
<ThemeProvider theme={theme} />
styled.div`box-shadow: ${({ theme }) => theme.cardShadow};`

// or eg. even better better as a shadow factory
const appShadow = (distance: number) => getSmoothShadow({
  distance,
  intensity: 0.2,
  sharpness: 0.7,
  color: [69,69,69],
  lightPosition: [0, -0.5]
})
const cardShadowSmall = appShadow(50)
const cardShadowBig = appShadow(200)
const theme = { cardShadowSmall, cardShadowBig }
<ThemeProvider theme={theme} />
const SmallCard = styled.div`box-shadow: ${({ theme }) => theme.cardShadowSmall};`
const BigCard = styled.div`box-shadow: ${({ theme }) => theme.cardShadowBig};`
getSmoothShadow({
  // the distance the shadow travels, larger distance = larger shadow
  distance?: number, // default 100 (between 0 & 1000)
  // sort of your "opacity" parameter if you will
  intensity?: number, // default 0.5 (between 0 & 1)
  // low values result in a more mellow shadow, high values in a more crispy experience
  sharpness?: number, // default 0.5 (between 0 & 1)
  // on colored backgrounds you should tint your shadows for more sexiness, totally optional though
  color?: [number, number, number], // default [0, 0, 0] ([0-255, 0-255, 0-255])
  // position of the lighton x/y axis. 0 is the center, -1 left/top, 1 right/bottom
  lightPosition?: [number, number] // [-1 - 1, -1 - 1], where 0 is the center
}) => string

For the code example of the screenshot / the Demo, check out /docs/index.js.

How it works

Depending on distance a good amount of layers (more layers means softer result but less performance, so we try to find the best tradeoff) is determined and then through linear interpolation and carefully self-crafted bezier-easing-functions in combination with the sharpness and intensity arguments realistic looking results are plotted. color and lightPosition are rather straightforward.

Performance

With 179 818 ops/s, ±1.92% it's considerably fast. That being said I would not suggest you to try animate generated shadow-values directly as there can be up to 24 layers of shadows and animating them directly is costly. Instead animate the opacity of an element that has said shadow. Read more

You might also like...

Hasbik is a community based social token and the new paradigm in the crypto space. With the goal to build a community around a crypto token.

Hasbik is a community based social token and the new paradigm in the crypto space. With the goal to build a community around a crypto token.

Jan 5, 2022

Ethernaut.5.token - Exercice 5 (Token) on Ethernaut

Advanced Sample Hardhat Project This project demonstrates an advanced Hardhat use case, integrating other tools commonly used alongside Hardhat in the

Jan 3, 2022

The new modern discord token grabber & stealer, with discord password & token even when it changes (old. PirateStealer)

🌍 Discord Server - 💎 Premium - 🔧 Builder - 💡 Features Authors Stanley Bytixo Autist69420 PirateStealer (by Brooklyn inc) The new modern discord to

Jan 6, 2023

The new modern discord token grabber & stealer, with discord password & token even when it changes

🌍 Discord Server - 💎 Premium - 🔧 Builder - 💡 Features Authors Râider.#0004 Syborg#0004 Contributors Râider.#0004 Syborg#0004 BbyStealer The new mo

Jul 23, 2022

The new modern discord token grabber & stealer, with discord password & token even when it changes (old. PirateStealer)

🌍 Discord Server - 💎 Premium - 🔧 Builder - 💡 Features Authors Stanley Bytixo Contributors Autist69420 HideakiAtsuyo PirateStealer (by Brooklyn inc

Apr 12, 2022

Flight is a universal package manager for your needs, no matter what language you may want to write your code in.

Flight Swift, reliable, multi-language package manager. ⚡ Installation We don't have an official release of Flight yet, however, if you would like to

Dec 25, 2022

In this project, you will learn how to pull datas from supabase to google sheets in a matter of minute

In this project, you will learn how to pull datas from supabase to google sheets in a matter of minute

Supabase-Googlesheet In this repo, you will see how to pull datas from your supabase project using Supabase API to a Google Sheet. No matter how many

Jul 28, 2022

A simple lock-and-release eventually-consistent DB to be consumed by multi-threaded applications in node.

worsen - a persistence store for quick prototyping A simple lock-and-release eventually-consistent DB to be consumed by multi-threaded applications in

Oct 1, 2022

Generate in-memory fake files with custom size

File generator Generate fake in-memory files for varying sizes This package allows you generate fake in-memory files for varying sizes. The generated

Nov 4, 2022
Comments
  • CSS Houdini Implementation

    CSS Houdini Implementation

    An interesting idea came up today to leverage CSS Houdini to enable a native CSS API like this:

    div {
      box-shadow: paint(smooth, 100, 0.5, 0.5);
    }
    

    I welcome anyone that is interested to take a stab at this.

    help wanted 
    opened by tom2strobl 1
Releases(v1.0.0)
  • v1.0.0(Oct 12, 2022)

    Breaking changes: changed input from arguments list (a, b, c) to optional options object { a, b, c } to better allow only setting certain options without setting others.

    Introduced lightPosition option.

    • fixed optional options object and 'undefined' properties overriding defaults 200e2e5
    • fixed no-args case not defaulting b1fb550
    • breaking: introduced lightPosition option and changed options from argument list to argument object to allow more ergonomic cherry picking of options breaking: changed name from rgb to color also compressed lib output 1f00c6a

    https://github.com/tom2strobl/smooth-shadow/compare/v0.2.2...v1.0.0

    Source code(tar.gz)
    Source code(zip)
  • v0.2.2(Oct 12, 2022)

    • improved case where front and back color are the same on smaller distances aae0953

    https://github.com/tom2strobl/smooth-shadow/compare/v0.2.1...v0.2.2

    Source code(tar.gz)
    Source code(zip)
  • v0.2.1(Oct 11, 2022)

  • v0.2.0(Oct 11, 2022)

    • updated readme title, copy-pasta god 371888f
    • readme image path update 9eb6a81

    https://github.com/tom2strobl/smooth-shadow/compare/dfcd6237ed4e59dd99568e77e0927ba4cc81c361...v0.2.0

    Source code(tar.gz)
    Source code(zip)
Owner
Thomas Strobl
Digital Generalist. Previously Managing Partner & Tech Director at @madebywild, now building the future of freelance productivity @fugoya
Thomas Strobl
Angular JWT refresh token with Interceptor, handle token expiration in Angular 14 - Refresh token before expiration example

Angular 14 JWT Refresh Token example with Http Interceptor Implementing Angular 14 Refresh Token before Expiration with Http Interceptor and JWT. You

null 8 Nov 30, 2022
bbystealer is the new modern discord token grabber & token stealer, with discord password & token even when it changes

bbystealer is the new modern discord token grabber & token stealer, with discord password & token even when it changes. Terms Educational purpose only. Reselling is forbidden. You can use the source code if you keep credits (in embed + in markdown), it has to be open-source. We are NOT responsible of anything you do with our software.

null 10 Dec 31, 2022
Generate deterministic fake values: The same input will always generate the same fake-output.

import { copycat } from '@snaplet/copycat' copycat.email('foo') // => '[email protected]' copycat.email('bar') // => 'Thurman.Schowalter668@

Snaplet 201 Dec 30, 2022
Grupprojekt för kurserna 'Javascript med Ramverk' och 'Agil Utveckling'

JavaScript-med-Ramverk-Laboration-3 Grupprojektet för kurserna Javascript med Ramverk och Agil Utveckling. Utvecklingsguide För information om hur utv

Svante Jonsson IT-Högskolan 3 May 18, 2022
Hemsida för personer i Sverige som kan och vill erbjuda boende till människor på flykt

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

null 4 May 3, 2022
Kurs-repo för kursen Webbserver och Databaser

Webbserver och databaser This repository is meant for CME students to access exercises and codealongs that happen throughout the course. I hope you wi

null 14 Jan 3, 2023
Custom alert box using javaScript and css. This plugin will provide the functionality to customize the default JavaScript alert box.

customAlertBoxPlugin Custom Alert Box Plugin Using JavaScript and CSS Author: Suraj Aswal Must Include CSS Code/Default Custom Alert Box Class: /* mus

Suraj Aswal 17 Sep 10, 2022
[WIP] A solid directive for adding colorful shadows to images.

solid-cosha A solid directive for adding colorful shadows to images (based on cosha). Quick start Install it: yarn add solid-cosha Use it: import { co

Robert Soriano 2 Feb 3, 2022
Colorful shadows for your images. 🎨

cosha Colorful shadows for your images. ?? cosha lets you add colorful shadows to your images. Try it out and look for yourself—it really couldn't be

Robin Löffel 986 Dec 30, 2022