I was wondering how can I find all CSS rules that apply to an element.
All the solutions that I've found so far either
use CSSStyleSheet.cssRules or CSSStyleSheet.rules properties. Doesn't work, because as of Chrome 64 you'll need to use a local development server to test functionality that depends on the CSS Object Model.
use getComputedStyles(), which is full of garbage like default/incorrect values and no #media or pseudo classes.
I want to copy an element from one site to another. I use Node.cloneNode(true) to clone the element. When I move the element to the other site, the styles inherited from the clone's classeNames and id don't exist anymore. That's why I want to find all CSS rules that apply to the element, so I can "reapply" them on the other site.
With window.getComputedStyles e.g. the width of the element is fixed to an exact amount of pixels, even if it was originally dynamic, :hover classes are ignored, all "sub"-classes like 'border-right', 'border-left' are defined even if the original div only had the short-hand property 'border' defined
How may I find all CSS Rules that apply to an element?
Related
It seems like when modifying the CSS properties of elements when using JS methods (CSSStyleSheet, with insertRule or deleteRule, or CSSStyleRule.style.setProperty()), the underlying CSS has been updated, but the page itself not not reflect the changes.
The changes are only realised upon some reflow trigger, say after I've changed the attribute of the element, even if it's an invalid one.
May be related to this question: What are the conditions under which a browser will re-assess and reapply CSS selectors and styles?
What is the recommended way to modify CSS using JS? Apart from changing class strings, or a hacky way to insert and delete attributes?
Note: Testing on Edge / Chromium
After reading your post, I'm not sure if you are aware of these simple ones:
element.style = stylestring (IE: "display:block; color:red;")
or
element.setAttribute('style', stylestring)
These will be treated as inline-styles. So changed properties will take priority over the external css and the effect will be immediate.
Now, is it the recommended way? That's a tough one, I'll let others answer this question, I'm not really a W3C guy...
Is it possible to convert a HTMLElement to a string putting all css styles (including the ones created dynamically with javascript) in style tags?
You can get this by accessing the outerHTML property
$("your element selector").prop("outerHTML");
This will return a string value of the object with any inline styling included.
This won't include styling included in separate css files. If this is something you do need then I would recommend looking at this and this previous question.
Getting the styles is not really an options there are css rules, inline styles and user agent styles that affects the actual look too.
You can always use jQuery css() method to get the calculated values of an element: ref css()
$(ele).css('height'); //Most of common properties are supported
But that will not do the work you are after.
I will save it as an image using rasterizeHTML.js and I need element looks exactly as in browser.
If that is your goal I can suggest you use other methods and libraries that already does a good job: html2canvas
in html2canvas the results are pretty accurate and the major limit is with images - but there are several methods to overcome that such as using the images as backgrounds.
Hope I helped.
I'm making a simple Chrome extension for personal use. I want to apply a CSS rule to all elements that match a class, even if they are rendered dynamically at some point after my extension's script is executed.
How can I do this in RAW javascript?
CSS rules will match any current and future elements in your document. The style gets applied as the document changes.
HTML5Rocks has a great article to give you a nice overview of how browsers work, including when and why layout and styling is applied.
I've been looking at a few different things I'd like to using JavaScript to tweak styles globally. I'd like to do this by changing the CSS rule that dictates the element's style (akin to doing this through the Inspector in Webkit), but after coming to https://developer.mozilla.org/en/DOM/CSSStyleRule I now don't know if this is even possible:
style
Returns the CSSStyleDeclaration object for the rule. Read only.
So, is there no way to change higher-level styles in JavaScript?
To modify your existing styles, either find the stylesheet in document.styleSheets or from the the .sheet property of the <style> or <link> element you want to modify. Then modify the properties in whatever rule they're located in (see https://developer.mozilla.org/en/DOM/CSSRuleList). I'd advice against using the CSSOM to modify properties, as browser support for modifying CSS properties through the CSSOM is pitiful (no browsers whatsoever support it). Instead, just set a string value.
If all you want to do is insert a new rule, just get a stylesheet from the method above, or document.documentElement.appendChild(document.createElementNS("http://www.w3.org/1999/xhtml","style")).sheet. Then use insertRule to add your rule.
CSS Styles can be created/changed programmatically via javascript, but that is not usually the easiest way to solve a problem because different browsers do it differently so cross-browser support is a bit of a pain unless you already have a library that abstracts that. You can see generally how to do it here: http://www.quirksmode.org/dom/changess.html.
If the styles you want to switch between are known in advance, then the easiest way to change between them is to define both those styles in a stylesheet, and use different class designations to trigger one vs. the other.
If you are just trying to affect one object or a small number of objects, you can simply add or remove a class name via javascript on the affected objects.
If there are large numbers of objects, then something I've done is to add a class name on the body tag to trigger the alternate style to take effect for all affected objects. It works like this:
Lots of these in your HTML:
<div class="foo"></div>
<div class="foo"></div>
<div class="foo"></div>
<div class="foo"></div>
Then, have two pre-defined CSS rules like this in this order:
.foo {background-color: #777;}
.alternate .foo {background-color: #F00;}
Then, using Javascript, any time you want to change to the alternate style, you simply do this (using jQuery or any favorite class library):
$(document.body).addClass("alternate");
To go back to the original style, you can just remove that class:
$(document.body).removeClass("alternate");
This doesn't have to be added to the body tag - it can be added to any common parent of all the affected objects.
I personally find this a lot simpler than programmatically creating style rules and it keeps the actual style information out of the code (where designer people who aren't programmers can more easily access it).
You can see this technique in action here: http://jsfiddle.net/jfriend00/UXKvg/
I have created a Javascript based element that can be embedded into websites. The Javascript itself adds the HTML code into a pre-defined HTML container and dynamically loads the necessary CSS file that contain the element's visual definitions.
The problem starts when the site itself has its own definitions for general items. For example: The site's CSS defines a certain list style which is applied on the element's list because the element's CSS doesn't define an explicit list style or if the site's CSS overrides the element's CSS definition.
For the time being, I was able to solve this specific issue by explicitly defining the list's style and adding the !important definition. However, I would definitely want to go for a more robust solution that will assure that:
1. CSS definitions from the site's CSS that are not explicitly defined in the element's CSS will not be applied on the element
2. I will not need to explicitly add the !important definition to every one of my CSS definitions
Is there a general way in which I can specify that a site's CSS will not be applied on a certain element or that only a certain CSS will be applied to a specific element?
Any help will be greatly appreciated.
You need to use a localised reset.
Grab an existing CSS reset, such as Eric Meyer's Reset Reloaded and namespace all the selectors with your parent element, e.g. #something a { ... }.
I was going to put up the same answer as Alex, but he beat me - but I was also going to add:
If you're not going to use #alex's suggestion then ultimately you have to explicitly style all of your elements the way that you want them to appear; using selectors that keep your styles local too (and don't interfere with the parent site) - in the same way that the localised reset is suggested.
Update
Or you could do what Google Translate and many other widget-type things do, usually a no-no but in dynamic scenarios I think perfectly acceptable; since the visual style of your elements is not just important to you but to the container site: use inline styles.
Final update
So I thought I'd just double check what Google Translate does. And of course it's an iFrame inject in addition to using inline styles. They no doubt use inline styles to maximise compatibility and so that the browser doesn't have to make another request to get the stylesheet; and they would be using an iFrame so they can ensure a consistent look and feel.
Consider both of those points in tandem - and weigh that up against the amount of work that might be required in resettting all the styles for a minority portion of the page; or defining rules for every CSS property you need to control - which, let's face it, is basically all visual CSS properties.
The iFrame solution actually seems to offer the best solution - if you can use it; hence I've +1'd the first comment by #roberkules on your question.