Extract CSS rules from any given element - javascript

I'm trying to find a way to extract all css rules from any given element (I have full access to the html, and css).
I have look into other solutions such as getComputedStyle, however, it doesn't help much with certain properties such as width or height. For example, I expect it to return width: 100% when applicable, but it always return the real width value in px. What I need is the CSS rule definition, not how it is actually rendered on the browser.
My last resort is to use some css-inliner such as juicejs then I can access the element.style.prop, but I think if these js inliners can turn css rules to inline css then they must have extracted the css rules along the way already? I tried to look into its source but if there is any module out there doing the job it would be much better than trying to extract the code from that library.

It amazes me that there are not many solutions available for this issue. I ended up finding 2 solutions that both work (there are probably some edge cases but I have not encountered yet)
Option 1: A getMatchedCSSRules implementation posted here:
https://stackoverflow.com/a/37958301/821517
Pros: short and concise
Cons: does not support pseudo selectors (yet)
Option 2: A very all library called CSSUtilities mentioned here:
https://stackoverflow.com/a/12023174/821517
Pros: it can handle pseudo selectors
Cons: very very old library which relies on another library that is deprecated.
I ended up using CSSUtilities and I had to make some changes (hacks) to make it work with the new js engines. I post both modified files here in hope that it will help others (and that errors I made can be spotted and suggested with fixes)
New files: https://gist.github.com/yellow1912/c9dbbab97497ec42489be55e8abe73c7
Please ensure that you visit this link to download the package which contains the document file: http://www.brothercake.com/site/resources/scripts/cssutilities/

Related

The css file does not appear in inspect google

Hi I'm an average in CSS but I did not understand why in many websites I find that this file does not appear and many theme I do not find the css file in charge of this class is this way in css I do not know.
I want to edit this class from the file but can not find the file?
Strangely, it's not the automatic properties of the browser.
Not necessary that class must have css written. Sometimes classes written to manage JavaScript.
You are looking at the final result of what is probably a CSS-in-JS approach that many popular tools out there provide. The original classes that the developer writes in their code are transformed into the sort of garbled looking classes when the build process is run.
The result is CSS classes that are unique and do not conflict in the traditional global CSS sense. This also means you cannot so easily track down the source of the code through your inspector unless the developer has generated and provided source maps as well.
A good example of one of these CSS-in-JS tools is Styled Components (https://www.styled-components.com/) but there are many others out there.

Block specific javascript statements from executing "globally" from a client side perspective

Dear Stackoverflow Community,
as you might see, this is my first post and a rather specific question I believe.
Here is the problem:
It is possible to block javascript as a whole or specific scripts as far as i could find out. What however if i globally want to stop the execution of specific javascript statements?
Practical example:
A website is utilising several javascripts many of which are useful and I would like to participate in their functionality with the permanent exclusion of any code that references overflow:hidden. I perceive that (CSS-Snippet?) to be malicious code by design. It can be easily circumvented and fixed through executing your own code. That's not what I'm talking about though.
Probable solutions:
- Remove the browsers capability of understanding that particular code
- Enforce overflow:auto
- Apply overflow:auto when the website is fully loaded automatically
The aforementioned solutions seem very unelegant to me and as you guys seem like a clever bunch maybe you can think of something less superfluous and practical.
All the goto addons I've tried only offer 1-off solutions or the need to repeat the task of counteracting those code snippets.
Current solution:
var r="html,body{overflow:auto !important;}";
var s=document.createElement("style");
s.type="text/css";
s.appendChild(document.createTextNode(r));
document.body.appendChild(s);
void 0;
Isn't there a way to tell FireFox (or chrome) to categorically ignore every single attempt to alter overflow:auto or similarly (perceived) malicious codes?
If you really want to set a property for all the elements in the website you could try this jQuery code
$('*').attr('style', ($('*').attr('style') || '') + ";color:black !important");
Here I get all the elements in the page and add my custom property in their style. In my case it was a black color, but you can have your overflow set to auto.
Check this Fiddle and you'll see that I set many colors to the texts in the page, both with inline styles and through CSS and then the jQuery script forces all of them to be black.
The explanation is that an inline rule is more "powerful" than CSS rules, so if you set an inline rule to be important it is applied to the element instead of the CSS rule (as it overwrites it).

When should I control background image change with CSS vs Javascript? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
This is more of a general practice question that a problem specific one but I'll give an example of what I mean. There are a lot of things you can control with CSS that you can also do with Javascript, but is one better to lean on than the other?
Example:
I have four buttons in a nav that are given a class of "selected" when the section they're associated with is in view. So I could either write a CSS statement for each button (or have Sass do it for me with a mixin)
#home-butt.selected{
background-image: url(images/home-up.png);}
#about-butt.selected{
background-image: url(images/about-up.png);}
#work-butt.selected{
background-image: url(images/work-up.png);}
#contact-butt.selected{
background-image: url(images/contact-up.png);}
Orrr I could write something in javascript to do the same thing. (*I gave the images a title attribute that matched the image name so it could pull from there).
title = $(this).attr('title');
$(this).find('img').css("background-image",
"url(" + 'images/' + (title) + '-up.png' + ")");
So my question is which is better to use? Is it the javascript because it's less lines of code? Or the CSS incase javascript is disabled? Or is this a very situational question where there isn't always a right or wrong answer?
Opinions and rebuttals are welcome!
To answer your question about "is one better to lean on than the other?"
Keep in mind, that CSS has a specific purpose. To apply the look to your application. JavaScript on the otherhand, is mostly the feel of your app. Always prefer CSS over JavaScript when editing styles.
The only time that you ever should modify styles using JavaScript is when you have a dynamic application, and need to change styles based on some unknown variable. Even then, a lot can be achieved with just using CSS.
Also keep in mind that you are using jQuery. think about jQuery's constructor. it is a CSS selector.
With the concept of CSS pseudo-classes introduced, there is very little that you cannot achieve style-wise with CSS.
In many cases where Javascript developing makes what I'm trying to accomplish much more easy and other cases where CSS does that to.
" In the end each "language" has its appropriate place in web development and used wisely can enhance both development and user experience. Learn what those uses are (I recommend experience learning) and apply wisely. In my experience, set in stone rules such as "Never use JS when a CSS solution exists" (paraphrased) are rarely best in the practical world. "
If you are working with layout, use CSS, if your creating the look and feel use CSS, if your doing animations use CSS3
If you attach event handlers or reacting to user input use JavaScript.
Usually you want to use CSS, because it's much faster than javascript. Also there are going to be users with javascript disabled, which aren't going to see your enhanced presentation if it relied on js function.
The usual answer is, use CSS when you can, because it will work with JavaScript disabled, and also because you don't have to deal with issues like waiting for elements being available in the DOM before referencing them.
But sometimes it depends. Keep in mind that:
Depending on the selector or properties you're changing you may have issues with browser compatibility.
If you're changing the image like in your example, you may see it flicker while the new image is loaded. You can avoid that by using a sprite image, or preloading the images with JavaScript.
As a general rule of thumb, I would use CSS for styling and JavaScript only to "make the page alive".
So the best and the most ideal use of JavaScript is to add and remove classes from elements
- classes, which your CSS is depend on.
Loading the jQuery library to perform this simple task is unnecessary and relying on javascript to apply background images to your img tags is unnecessary as well.
If it can be done properly in CSS, and work in all browsers, then it should be done in CSS.
Javascript is for more advanced or complex tasks, which require interaction or animations that CSS can't provide for all browsers (due to cross browser compatibility issues - check out caniuse.com)
In your example, if the .selected attribute is being given dynamically by javascript for instance:
makeSelected(elm)
{
document.getElementById(elm).className='selected';
}
then i would still personally add the styling for .selected in CSS instead of adding the image through javascript.
If you're adding .selected based on the current page you're on and not through javascript then I would recommend using CSS.
I prefer CSS over Script for one main reason Browser compatibility
There are just soooo many times when one script code or the other isn't compatible in one browser or the other (cough or just IE)
With css I haven't had such issues yet (touchwood) and also if there were any issues CSS's won't affect as much as script's which just don't let any other following codes to execute.
Let me provide my opinion.
Personally I don't believe a website should have a lot of "gimmicks" in terms of designing.
BY gimmicks I mean hovering effects, music in the background(absolute no-no) or other "eye-catching details". All of this looks good the first time but subsequently visitors get fed up with this distractions.
Without deviating from the main issue. CSS/JavaScript for styling.
Well they do exist hand in hand. The best example for this would be Bootstrap library. Although I have never used it personally but it seems amazing what can be achieved using CSS and JavaScript.
So, We will need both to design spectacular website. CSS helps in the basic designing and to make the website more responsive we use JavaScript and its derivative libraries like Jquery for all the finer looking stuff

how to reference elements in CSS or JS files for fastest parsing?

I'm trying to improve a websites rendering speed.
Both CSS and JS files mostly reference elements like this:
Javascript:
$('.some_element').doSth()
CSS:
.some_element { /* do something */ }
Just curious - is this the optimal way of referencing elements in terms of javascript parsing and website rendering? Wouldn't it be better to do something like div.some_element?
Thanks for some infos!
If speed is a priority you might want to switch to vanilla javascript as much as you can. Native javascript is faster than jQuery.
If you want to keep your jQuery selector use parent context to make the search for the element more efficient. Example $('#parent').find(child)
You can find more tips on javascript an jquery optimization on the web:
http://engineeredweb.com/blog/10/12/3-tips-make-your-jquery-selectors-faster/
div.some_element will be different than .some_element, if you don't just have divs that use the some_element class.
Maybe compare render times using Chrome's built-in developer tools (or an alternative) to see if it helps you, but I doubt it'll be significant.
The fastest way to find a single element is usually with an id, not a class:
document.getElementById("whatever")
If you have to use jQuery (which is not as fast as plain javascript), then you would use:
$("#whatever")
If speed is really important, you can resolve the DOM element once when the page loads and just save the direct DOM reference so you don't have to find it when your code actually executes later.
As with all questions of performance, the only real way to answer a performance question is to benchmark a couple of implementation options and actually test which is faster.

How can I read out the CSS text via Javascript as defined in the stylesheet?

I was thinking of using Javascript to automatically transform CSS3 attributes like border-radius, transform, box-shadow, etc. to their browser specific counterparts.
I did some research and found that you can iterate over the stylesheets defined via document.styleSheets. You can find the CSS rules via document.styleSheets[0].cssRules[0].cssText.
I want to modify the CSS rules that contain CSS3 attributes by injecting the browser specific attributes with the appropriate vendor-prefix, like -webkit-border-radius, moz-border-radius, etc.
However, it seems that the cssText property is preprocessed in each browser, to filter out CSS attributes that it doesn't understand. That practically breaks this idea.
Question: is there any way to retrieve the CSS text exactly as defined in the stylesheet? Or: is there another way to accomplish this via Javascript? I'd like to maintain clean CSS files without the need for defining each attribute multiple times for each specific browser.
Why don't you just create stylesheets that have each browsers unique Pre-CSS3 counterparts in them already? As you mentioned, each browser filters out properties they don't recognize. It doesn't matter if you have -webkit-border-radius and moz-border-radius and border-radius all defined simultaniously for the same css selector. If a browser recognizes one of them, it'll be used, and if it doesn't, it'll be discarded. Even if a browser recognizes multiple versions, they are most likely going to have identical values, so it wouldn't matter.
Looks like you have done your research on this well. It is not possible by accessing the CSSStyleDeclaration or the CSSRuleList object as unindentified properties get filtered out, which is a an implementation bug in most major browsers as they are supposed to list all properties - even ones they don't understand. See a related question for more on this.
The remaining alternatives require a bit too much work as #Sarfaraz already mentioned. It all boils down to parsing everything by hand and re-doing the work browsers have already done for us. Assuming your style declarations are inline, either in <style> tags, or as an element's style attribute, then you would have to parse the text and construct a map of all interesting CSS3 properties. With an inline-attribute, it's basically parsing text somewhat similar to:
`prop1: value; prop2: value2; ..`
See #Nick Craver's answer to a similar question, where he has linked to a regex approach for doing this.
With inline tags, the text to be parsed will be of the form:
[selector] {
prop1: value1;
prop2: value2;
...
}
...
This is an oversimplification ignoring all grammar production rules, and there are loads of issues to be handled here.
If the stylesheets are external, and are referenced inside the page, then you would have to lookup the <link> elements having an attribute rel equal to "stylesheet", and get their href property. Also, parse the url for imported stylesheets. Once you have these urls, you can make an AJAX call to fetch the actual contents of these stylesheets assuming nothing is blocking the call on the server side. Once you have the text from each file, it's basically a parsing step same as above, and adding necessary rules using insertRule or addRule depending on the browser.
There may be open-source CSS parsers that could help you in this.
This may be a long way of saying that I think #jrista's solution is a pretty good one. If you don't want to write all permutations of vendor-specific code, then an easier and better approach would be to have a CSS generation layer that's part of some build process which generates all permutations and spits out CSS files.
This layer could also contain optimizations by inspecting the User-Agent header and only generate the required styles, which is essentially what GWT does (but it generates all possible permutations beforehand, instead of doing it at runtime).
This may be a serious undertaking, so at the end of the day, you have to evaluate your options and see if the effort of achieving code-purity outweighs the benefits of having a little redundancy.
Isn't it what IE7.js (and IE8.js and IE9.js) already do? Maybe you should take a look to the approach taken by Dean Edwards to add support for min-height, opacity, many CSS3 selectors, position:fixed; and overflow:visible; to these old browsers we all hate.
EDIT: btw, I prefer jrista solution: prefix CSS3 properties with -moz and -webkit and -ms and -o when needed.
It's an annoying task we'll have to do for ~5 years but it's far LESS annoying than if the W3C changed its mind about some properties (CSS3 modules are far from Recommendation). Then your script will still recognize the old syntax and give it to browsers whocan tell the difference between -vendor-property: oldsyntax_from_2010; and property: newsyntax_from_2015;
And what would you do if you find -moz-border-radius: 4px; border-radius: 20px; ; which one is the good one?
EDIT2: http://css3generator.com/ is a handy tool if you don't want to stuff your brain with details like syntax differences between -webkit-border-bottom-right-radius and -moz-border-radius-bottomright :)

Categories