Just for fun - this is wildly inefficient, but you could parse each stylesheet, check if each rule matches the element, if it does, add the rule to a list of matches. Then, for each match, check if setting the inline style of that element to that rule changes the computed value, if it doesn't, assume that is the rule in use:
const getCssActualValue = (el, property) => {
const matches = new Set();
const allCSS = [...document.styleSheets]
.map(styleSheet => {
try {
return [...styleSheet.cssRules]
.map(rule => rule.cssText)
.join('');
} catch (e) {
console.log('Access to stylesheet %s is denied. Ignoring...', styleSheet.href);
}
})
.filter(Boolean)
.map(rule => rule.split('}'))
.forEach((styleSheet) => {
styleSheet.forEach((rule) => {
const [selector, styles] = rule.split(' {');
try {
if (selector && el.matches(selector)) {
styles.split(';').map(el => el.trim()).forEach((rule) => {
const [prop, val] = rule.split(': ')
if (prop === property) {
matches.add(val);
}
});
}
} catch {}
});
});
return Array.from(matches);
}
const getCurrentCssValue = (el, property) => {
const matches = getCssActualValue(el, property);
const current = getComputedStyle(el)[property];
const currentInline = el.style[property];
for (const match of matches) {
el.style[property] = match;
if (getComputedStyle(el)[property] === current) {
el.style[property] = currentInline;
console.log({match});
return match;
}
}
el.style[property] = currentInline;
return currentInline;
}
const property = 'height';
const el = document.getElementById('test');
el.innerText = getCurrentCssValue(el, property);
#test{
width:200px;
height:20vh;
background:LawnGreen;
}
<div id="test"></div>