box-shadow-radius-generated-ref.html (2294B)
1 <!DOCTYPE html> 2 <title>Box Shadow Border Radius (Outset)</title> 3 <link rel="help" href="https://www.w3.org/TR/css-backgrounds-3/#shadow-shape"> 4 <div id="shadow"></div> 5 <div id="target"></div><style> 6 #shadow { 7 position: absolute; 8 background: black; 9 top: calc(100px - var(--spread) * 1px); 10 left: calc(100px - var(--spread) * 1px); 11 width: calc((var(--width) + var(--spread) * 2) * 1px); 12 height: calc((var(--height) + var(--spread) * 2) * 1px); 13 } 14 15 #target { 16 position: absolute; 17 top: 100px; 18 left: 100px; 19 width: calc(var(--width) * 1px); 20 height: calc(var(--height) * 1px); 21 border-radius: var(--radius); 22 box-shadow: 0 0 0 var(--spread) black; 23 background: green; 24 } 25 </style> 26 27 <script> 28 const {searchParams} = new URL(location.href); 29 const width = +searchParams.get('width'); 30 const height = +searchParams.get('height'); 31 const spread = +searchParams.get('spread'); 32 for (const param of searchParams) { 33 document.documentElement.style.setProperty(`--${param[0]}`, param[1]); 34 } 35 function adjusted_radius(radius_css) { 36 let [radius_width, radius_height] = radius_css.split(' '); 37 if (typeof radius_height === 'undefined') 38 radius_height = radius_width; 39 40 if (radius_width.endsWith('%')) 41 radius_width = parseFloat(radius_width) / 100 * width; 42 else 43 radius_width = parseFloat(radius_width); 44 45 if (radius_height.endsWith('%')) 46 radius_height = parseFloat(radius_height) / 100 * height; 47 else 48 radius_height = parseFloat(radius_height); 49 50 const coverage = Math.min( 51 2 * radius_width / width, 52 2 * radius_height / height 53 ) || 0; 54 55 return [radius_width, radius_height].map(value => { 56 if (value > spread || coverage > 1) 57 return value + spread; 58 else 59 return value + spread * (1 - (1 - value / spread)**3 * (1 - coverage ** 3)); 60 }).map(v => v + 'px').join(' '); 61 } 62 63 const target = document.getElementById('target'); 64 const shadow = document.getElementById('shadow'); 65 const computed_style = getComputedStyle(target); 66 for (const radius_prop of ['borderTopLeftRadius', 'borderTopRightRadius', 'borderBottomRightRadius', 'borderBottomLeftRadius']) 67 shadow.style[radius_prop] = adjusted_radius(computed_style[radius_prop]); 68 69 </script>