Reverse engineering which CSS rules apply to a given DOM element? - css

Please note: I found this question as well as this one, but both of their answers involve writing and executing customized JS. My question here is about how to wield Chrome Dev Tools (or similar) to accomplish the same thing in real-time.
I have a quasi-legacy JVM app that serves (and creates as part of its build pipeline) all sorts of nasty and messy CSS files.
I'm wondering if Chrome Dev Tools (or any other modern OSS webdev tool for that matter) has a "reverse engineering" feature in it that allows you to click on an HTML element and get a list of all the CSS rules that apply to it. And, not only that, but which rules are overriding other rules.
This way, when I need to tweak my CSS, it's less of a wild goose chase to figure out which rules are coming from which CSS files and that are actually being applied to the live element at runtime.
Any ideas?

Yes, in Chrome DevTools (F12 in Windows / Option+Cmd+I in OSX) within the Elements panel you can click on an element and see the applied CSS rules on the right-hand side. The overridden styles or classes are crossed out, and you can see the file name in which the CSS rule comes from. See below:
element.style refers to inline styles. For example, if I modified the selected element to be <div class="container" style="background-color:#000">...</div>, background-color:#000 will show up in the that section.
#content refers to the div element with the associated id of 'content'. The checkboxes that are checked on the right indicate that they have been applied with no overriding. You can check and uncheck these to play around with the styles so that you can see what you should change in your source code.
The html, body, div, span etc. allows multiple selectors to use the same styles. All the selectors in that comma-separated list will have the styles, except some may be overridden by other CSS rules - in this case, margin and padding are overridden by the more specific #content selector.
The next block is for user agent styles. These are styles that are applied by the browser, and each browser may apply different ones. This can be a problem if you have more specific rules defined yourself. Many people use normalizers to make sure things remain consistent among browsers. Check out Normalize
The inherited section shows all the styles that are inherited from parent styles. In this example, the text-align: left style was applied from the .container class as that is the parent element and the #content element didn't override it explicitly.
Update
Added better quality screenshot (thanks to #SLaks)
Added keyboard shortcuts for access (thanks to #NKD)
Added simple explanations of the sections of the Styles panel on the right.

Modern browsers have an "inspector" option that allow you to select a piece of generated HTML and view the CSS applied to it. Each one varies slightly, but normally hitting F12 will get you going.

Related

Are css errors recorded anywhere?

I understand that if a sytle is overridden then it is crossed out in Google Chrome tools and then you can go to the Computed tab to see, which element has overridden the style.
Say I have some css like this:
.myClass
{
position:static;
top: 20px;
}
This is clearly wrong because the top attribute does not work with positions that are static. When I load the webpage in Google Chrome and press F12; the style appears under the styles tab as if it was applied to the webpage, which I find a little confusing.
Does Google Chrome (or any other browser/tool) tell you what the error is e.g. "cannot apply top to statically applied element" (like you get in Visual Studio when there is an error in your code e.g. NullPointerException).
A CSS class is a set of rules applicable to any element on your page that also can change during the live time of the page. As mentioned in Dais comment, properties are inherited and cascade down.
There is no reliable way to validate a set of CSS rules, because they all interplay each other and are about to change. Especially if you ask for a feature in your IDE like the NullPointerException hint this won't work, because CSS classes are composable and are JIT compiled. An IDE could not know beforehand which class are combined with other classes assigned to which elements in regards to the DOM tree at a specific app time state.
Mozilla Firefox has such a feature. It tells you why a rule isn't applied directly in the Inspector.

Does the Chrome browser development tools respect style changes specifying !important?

I'm doing a bit of CSS troubleshooting and, as you can imagine, I'm having a tough time getting a div to style the way I want it too. In Chrome, I've opened the development window and I've selected my element to inspect the style settings.
I need to do a quick visual test of some of my changes from within a specific selector. Note, I'm not looking to declare a temporary, specific value for the element.
I've found the selector, and the respective CSS property and as I knew, it is crossed out because a CSS definition of higher precedence is overriding it. However, for my test I added !important after the property value but it did not update my element and remained crossed out.
We have some very complex CSS. There is a chance that it's somehow being overridden but I wanted to be sure-- in Chrome browser, within the development window, if you override a style specified for an object, adding !important should it work?
Does the Chrome browser development tools respect style changes specifying !important?
Yes it does respect the specificity.
You can however test the specificity of your rule before using it in the devtools (or anyplace for that matter) here

How to reset all styles of a div and decedents back to Chrome defaults

I'm not sure this is possible, but id like to set all user styles back to chrome defaults for div and descendants.
I'm building a Chrome plugin that creates a popup on any web page, however due to the fact every page has a plethora of custom styles, trying to track down every inconsistency and overwrite it with my divs (and descendants) custom style, it is becoming a nightmare.
Every time I think I've covered all bases another site implements something else that needs to be overridden.
What would be the easiest approach to standardize my popup in this situation?
One approach I can think of is to (bite the bullet) and get a hold of the the default Chrome CSS styles and implement them into a series of catch all descendant selectors, however surely there is a better way.
If you want to be absolutely sure that the styling of your elements is not affected by the web-page's CSS, there are 2 possible solutions:
Use an iframe to implement your popup. (This solution is "safe" and simple enough, but based on the kind of interaction between the popup and the web-page it might become cumbersome.)
Utilize the Shadow DOM. (This is probably the "proper" solution, but the implementation might be a little more complicated.)
Some resources regarding the 2nd solution:
An introductory tutorial.
An actual example of incorporating the "Shadow DOM" concept into a Chrome extension:
RobW's Display Anchors extension
There is a third option worth discussing and rejecting, which is to reset all the style properties of the div and its descendents to its default value. Pseudo-code:
#my-div, #my-div * {
#for-every-css-property {
%propertyName: initial !important;
}
}
This answer shows an attempt at such a solution. It uses specific values instead of initial which will work in older browsers without the initial keyword, but will not correctly reset elements which have a different default from the base (e.g. user566245 mentions that textarea elements should have a border).
Issues:
Unfortunately initial is not actually the browser's default value.
If we don't use !important above then there is a risk that the page might have provided a rule with a more specific elector which overrides our own. For example if the page specified properties for table > tr > td then this would be applied over our rule because that selector is more specific than #my-div *.
Since we do use !important, any custom styling we want to do after the reset must also use !important on every property.
If the page happens to inject any additional CSS styles after ours that uses !important then these can override our reset.
It is rather inefficient. We are asking the browser to apply a huge bunch of CSS rules to every element under our div.
Vendor-specific properties should also be reset. (E.g. -webkit-animation-name.)
If new CSS properties come into existence in future, you will need to update your list.
Whilst this solution can be applied to current browsers, it is rather horrible, so roll on Shadow DOM! I would recommend the <iframe> solution in the meantime.
I don't know if anyone has tried this, but a more efficient solution might be to use Javascript to detect what site-defined CSS properties could be problematic, and reset only those.

find out what class is affecting a particular element

Is there a way to see exactly which declaration is affecting an element. Rather than looking at a million properties in the Firebug inspector, where depending on how many classes something is assigned may contain a lot of declarations that are lower precedence and therefore not applied. It can get lengthy to find which particular declaration is in fact affecting your element. I see long ignored declarations like this:
ul {
color: green;
}
"Computed style" will show you the end result of all the hierarchies, but not where the style derives from. Maybe I'm missing something simple. Thanks much!
JSBIN
Edit:
I've heard that I should be able to expand attributes in the Computed tag, however I don't see where that option is available. I can see that the font-size is 13.333px, but no option to see where that's coming from.
Yes, in Firebug select the element and then click on the 'Computed' tab (when viewing the HTML frame). Here you will see a list of CSS properties than can be expanded to show the location of the relevant CSS.
The Computed side panel can give you this info.
Note that it just shows the CSS trace - i.e. the styles that are affecting a specific CSS property - for those properties, which are actually changed by the CSS rules of your stylesheet. Though it can display all computed values for an element. To hide the unchanged ones you can uncheck the option Show User Agent CSS.
Also please ensure that you have a current version of Firefox installed (current stable is 20.0.1). Firebug internally uses some APIs for the style tracing, which are just available on newer versions of Firefox.
In Chrome DevTools there is 'computed style' panel which shows you the list of styles for an element property and their locations. For example see the screenshot for text-decoration property.

How to copy a CSS style from a website for re-use

I am frustrated. I have one website where my drop-down CSS menu works and another where it doesn't.
Their stylesheets differ wildly and, although I have tried to manually copy the menu styles from one to the other, but with no success.
Is their any tool which will let me (like FireDebug) click on a page section (the menu) and then copy the rules which affect that section - ignoring those which are hidden by other rules - so that I can post them into the second site's stylesheet.
It seems that rather than having multiple styles affecting the menu and trying to sort out which have precedence, I'd like to have some software sort it out and generate a single combined rule ... if you see what I mean.
Both FireBug and the inbuilt Chrome Dev Tools show you what styles are being utilised by the selected element. I don't work with FireBug much, but I know the Chrome Dev Tools will cross out overrided styles and even show default user-stylesheets where applicable. It's also kind of nifty when inline styles are applied, eg for a table the "frame" attribute, as it converts these to CSS and displays it as part of the styling ;)
Sounds like you've got problems with accidental inheritance. Try to make sure your CSS selectors are only referencing the elements you want to style. Otherwise things get messy, and stuff like this happens.

Resources