noomorph
noomorph

Reputation: 935

How to approximate CSS box-shadow property using solid border only?

Please note that the question is not about CSS, rather about imaging, colors and a bit of mathematics. We are not talking here about how to do things in CSS. Make sure your answer does not contain a single line of CSS. Mathematics, tables, images, and formulas only, please.

I need a way (data table, formula, whatever) to calculate good enough values of border-width and border-color's alpha channel (assuming that we use border-style: solid) required to mimic blur-radius and spread-radius of box shadow of the same color (assuming there are no X and Y offsets), at least, from the point of human's eye perception.

Below is an example of black rgb(0,0,0) color and blur-radius ranging from 1px to 8px.

Color = 000, Blur = 1px Color = 000, Blur = 2px Color = 000, Blur = 3px Color = 000, Blur = 4px Color = 000, Blur = 5px Color = 000, Blur = 6px Color = 000, Blur = 7px Color = 000, Blur = 8px

Currently, I'm building a data table of opacities for every next shadow pixel depending on the blur value, and if we presume that alpha blending takes place (white+black), then for the first three pixels opacities look this way (at least, in Google Chrome):

Opacity of black depending on shadow blur and pixel index

But still, even if I collect some empirical evidence and try out a few ideas, I don't know how to compare quantitatively my approximations and the original box-shadow version. If I can't measure, I can't tell whether an idea really works.

Maybe you've got some ideas how to pick best matching border width and color?

Thanks in advance.

Upvotes: 4

Views: 316

Answers (1)

noomorph
noomorph

Reputation: 935

Sometimes we have to answer our own questions. What did I do to answer mine - see below:

I've prepared 16x16 grid of Chrome screenshots (120px x 120px) using this utility HTML:

https://noomorph.com/approximate-box-shadow-using-border/screenshotter/

It renders a grid of 40x40 squares with shadow blur = 0..15px and shadow size =0..15px.

Grid of combinations

Then I've cut the big page screenshot (1920x1920) to 256 smaller ones like this one in the link below. My snake_case convention was <shadow-size>_<shadow-blur>.png :

https://github.com/noomorph/approximate-box-shadow-using-border/blob/master/scripts/00_15.png

Using ImageMagick convert, grep, sed, sort, uniq I've produced stats for every image:

https://github.com/noomorph/approximate-box-shadow-using-border/blob/master/scripts/00_15.png.stats

Using this tiny script I produced JSON array of cases like { size, blur, colors: [{ count, value }]}:

https://github.com/noomorph/approximate-box-shadow-using-border/blob/master/scripts/aggregate_stats.js

Then using simple arithmetics, basic distance formula D=(C1-C2)^2 (where C1 and C2 are gray channels of two colors respectively) and brute force (border-width=0..20 and RGB grayscale channel=1..255) I've got the mapping you can see on my demo site I've built for this:

https://noomorph.com/approximate-box-shadow-using-border/

Demo screenshot

I was trying to build some 3D and 4D plots, but still not sure about the nature of the correlation between box-shadow and border. I sincerely hope that my small research helps somebody in the future.

3D Plot

Happy hacking!

Upvotes: 0

Related Questions