admin管理员组文章数量:1291913
I can get all css properties for an element with document.stylesheets but some of those are not active because those properties are overwritten. In firebug (chrome developer tools also has this feature), if there's an overwritten css property, you will see something like that:
The only way I can think of is paring active css property for the element (in jQuery $(element).css(property)
) and defined css property in document.stylesheets
but it's not a reliable way to do it. Any suggestion?
I can get all css properties for an element with document.stylesheets but some of those are not active because those properties are overwritten. In firebug (chrome developer tools also has this feature), if there's an overwritten css property, you will see something like that:
The only way I can think of is paring active css property for the element (in jQuery $(element).css(property)
) and defined css property in document.stylesheets
but it's not a reliable way to do it. Any suggestion?
- The browser has to know, because it calculates the specificity of the selectors to determine the final oute. All the Dev Tools are doing is keeping track of those calculations and showing you them. To do the same in JS, you'd have to construct an entire CSS parser... – Niet the Dark Absol Commented Jun 6, 2012 at 15:27
- @Kolink, thanks. it seems there's no way to track browser's calculations without any extension, right? – burak emre Commented Jun 6, 2012 at 15:45
- I may be missing something but I can see in DevTools that overwritten properties are crossed over in the same way as they are in firebug (imgur./W9liZs8). So, what's the issue here? – Konrad Dzwinel Commented Aug 12, 2013 at 8:55
- 1 Why are you trying to do this? Is there an underlying problem that this may solve? (if so, maybe we can help with other solutions to THAT problem.) – andi Commented Aug 14, 2013 at 15:32
- @andi this can be useful for website builders, and apps like that. – iConnor Commented Aug 16, 2013 at 11:42
3 Answers
Reset to default 8 +100In webkit, you can use getMatchedCSSRules
to achieve what you want. It returns a CSS Rule set in order of inheritance applied by the browser and it is what the webkit inspector used some time ago. For Gecko based browsers like Firefox there seems to be a polyfill available here although I've not tested it.
A basic, working solution
The following code is also available as a fiddle
Because getMatchedCSSRules
only works with inline stylesheets, you will first have to inline your linked stylesheets:
function inlineStyles() {
var stylesheets = document.getElementsByTagName('link'),
head = document.getElementsByTagName('head')[0];
for (var i = 0; i < stylesheets.length; i++) {
if (stylesheets[i].getAttribute('rel') == 'stylesheet') {
(function (stylesheet) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", stylesheet.getAttribute('href'), true);
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var inlineStyle = document.createElement('style');
inlineStyle.setAttribute('type', 'text/css');
inlineStyle.innerText = xmlhttp.responseText;
head.replaceChild(inlineStyle, stylesheet);
}
};
xmlhttp.send();
})(stylesheets[i]);
} else {
continue;
}
};
}
Then, the big chunk: This is a first shot, improve at will. It can handle inherit
rules and up to one !important
definition, but that's it. For really plicated setups, this will have to be improved:
function getStyle(s, id) {
var element = typeof id === 'string' ? document.getElementById(id) : id,
css = window.getMatchedCSSRules(element),
style = window.getComputedStyle(element),
value = style[s],
styles = [],
rules = [],
inherited, currentRule;
// if there's a puted style, start calculation
if (value) {
// add matched rules if there are any
if (css) {
for (var i = 0; i < css.length; i++) {
styles.push(css[i]);
}
}
// add the element style attribute as a matched rule
styles.push({
style: element.style,
cssText: 'element.style {' + element.getAttribute('style') + ' }'
});
for (var i = styles.length - 1; i >= 0; i--) {
var def = styles[i],
rule = {
index: rules.length,
style: s,
value: styles[i].style[s],
cssText: def.cssText
};
if (rule.value == 'inherit' && !currentRule) {
if (inherited = getInherited(element, s, value)) {
rule.inheritedFrom = inherited;
currentRule = rule;
inherited = undefined;
} else {
rules.push(rule);
}
} else if (rule.value == 'inherit' && currentRule && isImportant(s, value, def.cssText)) {
if (inherited = getInherited(element, s, def)) {
rule.inheritedFrom = inherited;
rules.splice(currentRule.index, 0, currentRule);
currentRule = rule;
inherited = undefined;
} else {
rules.push(rule);
}
} else if (rule.value == value && !currentRule) {
currentRule = rule;
} else if (rule.value == value && currentRule && isImportant(s, value, def.cssText)) {
rules.splice(currentRule.index, 0, currentRule);
currentRule = rule;
} else if (rule.value.length) {
rules.push(rule)
}
}
return {
current: currentRule,
overwritten: rules
};
} else {
return false;
}
}
If Inheritance is taking place, we walk up the DOM Nodes to find the element that defines the CSS Rule with this helper function and get its style:
function getInherited(element, s, value) {
while (element.parentNode && window.getComputedStyle(element.parentNode)[s] == value) {
element = element.parentNode;
}
if (element) {
return getStyle(s, element).current;
} else {
return null;
}
}
We determine if a CSS Rule is marked as important with this helper function:
function isImportant(s, style, text) {
return new RegExp(s.replace(/([A-Z])/g, '-$1').toLowerCase() + ':\\s+' + style + '\\s+!important').test(text)
}
Have a look at the fiddle to see it working
This snippet may be useful to you, its helped me in the past, apply it in one of your CSS files, and you will be able to see what objects are being overridden by other class / id rules by finding the specific places where elements CSS declarations are, and by tracking their parents. My guess is you're having issues with inheritance.
* { outline: 2px dotted red }
* * { outline: 2px dotted green }
* * * { outline: 2px dotted orange }
* * * * { outline: 2px dotted blue }
* * * * * { outline: 1px solid red }
* * * * * * { outline: 1px solid green }
* * * * * * * { outline: 1px solid orange }
* * * * * * * * { outline: 1px solid blue }
Alternatively you could add a :hover attribute to those, and it would make it a bit easier to navigate, but the basic principal of the snippet is to show you the nesting of elements, and may help you to determine where the issues in your CSS are
You would have to parse the CSS files that are linked to the page to be able to determine the styles that are being used. You would also have to determine what properties can be used to target elements in CSS. Here is the flow you would have to follow:
Elements can be targets by: tags, IDs, classes, pseudo classes and inheritance
You would then have a given element, for instance:
<a href="#" id="link" class="button">Woop</a>
That element has several selectors associated to it by default. All elements can inherit parent CSS, so you would have to create a hierarchy of parent elements. Later styles will take precedence. You then have to take into account the tag a
and any parent that also shares this selector such as body a
. Likewise, you would have to create a hierarchy of inherited attributes. You would repeat this process for classes, attributes, and pseudo-classes. Once you have piled your list of trees for the element, you can then parse the CSS documents for the appropriate styles.
This is definitely a huge undertaking and there is no sense in reinventing the wheel. What I would suggest is looking at open source projects that have already done this. WebKit is an open-source project that has already built this system. Consider using their implementation as a starting point and make your changes from there.
本文标签: javascriptHow can I detect overwritten css propertiesStack Overflow
版权声明:本文标题:javascript - How can I detect overwritten css properties? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741541541a2384349.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论