您可能知道,box-shadow不是box-model的一部分。那么计算添加到元素的box-shadow宽度的好方法是什么?
更新:我需要知道元素的总宽度,包括阴影宽度。
您可能知道,box-shadow不是box-model的一部分。那么计算添加到元素的box-shadow宽度的好方法是什么?
更新:我需要知道元素的总宽度,包括阴影宽度。
你可以简单地添加一个与 box-shadow 相等的 margin。例如:
box-shadow: 0 0 10px #008800;
margin: 10px;
box-shadow: 5px 5px 10px #080;
margin: 5px 15px 15px 5px;
这里的偏移量是5像素,再加上10像素的长度。在扩展的情况下,我们可以继续添加边距值来考虑这一点。
box-shadow: 5px 5px 10px 7px #080;
margin: 12px 21px 21px 12px;
使用边距可以避免阴影与页面上其他对象重叠。
精确的宽度会因浏览器而异。每个浏览器呈现的阴影都不同。如果必须为对象提供硬计算,我猜它可能是这样的(参考CSS属性)
box-shadow: h-shadow v-shadow blur spread color;
top = (spread - v_shadow + 0.5*blur)
right = (spread + h_shadow + 0.5*blur)
bottom = (spread + v_shadow + 0.5*blur)
left = (spread - h_shadow + 0.5*blur)
模糊系数是一个估计值,可能需要稍作调整。个人建议不要使用偏移量,但此处仅为演示其使用位置。
这里有一个jsfiddle示例,以查看它的效果http://jsfiddle.net/YvqZV/4/
我只是在扩展@samuel.molinski的答案,创建一个完整的函数,该函数接受一个框阴影并返回宽度。
function getBoxShadowWidths(boxShadow) {
// not supporting multiple box shadow declarations for now
if ((boxShadow.match(/(rgb|#)/g) || []).length > 1) {
return false;
}
const regEx = /(\d(?=(px|\s)))/g;
const matches = [];
// box-shadow can have anywhere from 2-4 values, including horizontal offset, vertical offset,
// blur, and spread. Below finds each one and pushes it into an array (regEx.exec when used in succession
// with a global regex will find each match.
let match = regEx.exec(boxShadow);
while (match != null) {
matches.push(match[0]);
match = regEx.exec(boxShadow);
}
// default blur & spread to zero px if not found by the regex
const [hOffset = 0, vOffset = 0, blur = 0, spread = 0] = matches.map(parseFloat);
// calculate approximate widths by the distance taken up by each side of the box shadow after normalizing
// the offsets with the spread and accounting for the added distance resulting from the blur
// See https://msdn.microsoft.com/en-us/hh867550.aspx - "the blurring effect should approximate the
// Gaussian blur with a standard deviation equal to HALF of the blur radius"
const top = spread - vOffset + 0.5 * blur;
const right = spread + hOffset + 0.5 * blur;
const bottom = spread + vOffset + 0.5 * blur;
const left = spread - hOffset + 0.5 * blur;
return { top, right, bottom, left };
}
感谢 @Joey 提供的函数。我增加了对多个值的支持:
function getBoxShadowWidths(boxShadowValues) {
const regEx = /(\d(?=(px|\s)))/g
const widths = { top: 0, right: 0, bottom: 0, left: 0 }
boxShadowValues.split(/\s*,\s*/).forEach(boxShadowValue => {
const matches = []
// box-shadow can have anywhere from 2-4 values, including horizontal offset, vertical offset, blur, and spread.
// Below finds each one and pushes it into an array (regEx.exec when used in succession with a global regex will find each match.
let match = regEx.exec(boxShadowValue)
while (match != null) {
matches.push(match[0])
match = regEx.exec(boxShadowValue)
}
// default blur & spread to zero px if not found by the regex
const [hOffset = 0, vOffset = 0, blur = 0, spread = 0] = matches.map(parseFloat)
// calculate approximate widths by the distance taken up by each side of the box shadow after normalizing
// the offsets with the spread and accounting for the added distance resulting from the blur
// See https://msdn.microsoft.com/en-us/hh867550.aspx - "the blurring effect should approximate the
// Gaussian blur with a standard deviation equal to HALF of the blur radius"
const actualWidths = {
top: spread - vOffset + 0.5 * blur,
right: spread + hOffset + 0.5 * blur,
bottom: spread + vOffset + 0.5 * blur,
left: spread - hOffset + 0.5 * blur,
}
Object.keys(actualWidths).forEach(side => {
widths[side] = Math.max(widths[side], actualWidths[side])
})
})
return widths
}