Apply CSS rule to all future elements - javascript

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.

Related

Find all CSS rules that apply to an element (2018)

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?

JS/DOM optimization: using :after content styling instead of altering innerHTML

Basically, given that all possible contents of an element are known in advance, you can use a bunch of :after content styles instead of altering the innerHTML of the element. Just change the class to get new content.
My profiling in Chrome indicates that this does improve performance a bit, but I'm not entirely sure, as the cost might then be hidden somewhere else? And I'm not sure if it's a bad idea for other browsers besides Chrome. Any thoughts on this?
Please note that the context here is for 60 frames per second simulations/visualisations, so in this context 2 vs 4 milliseconds is a big and significant difference, which it might not be in the context of a page load.
Example styles for numbering can be seen here: https://github.com/magwo/elevatorsaga/blob/2fa5dc0c0397d0565ce5dcc45c68b19d924a4955/style.css#L290
pseudo-elements are design elements they are not content, they don't appear in the source code, they don't exist in the DOM, they wont be crawled by search engines, you cannot select or copy them, and of course, they don't exist without CSS, which is a style-sheet.
It may be faster, but that is probably because it is not content. And maybe it is easier for the browser to change a class than change the content of an element.
The question is, do you want to change the content, or the visual representation of it?
As for the implementation, I believe that having every possible content loaded in to a CSS is not an optimization, the same thing applies if you are planning to request a new CSS file for every new content change.
Finally, at least for now, you can't style individual parts of the content of a pseudo-element, you can't add paragraphs,spans and other markup.

Changing inline style vs. changing external stylesheet style using JS

What are the benefits of changing particular bits of style inline in the HTML or changing it from an external stylesheet using Javascript?
For instance, this post explains how one can accomplish changing styles from an external stylesheet. However, the process seems to be much more complicated than changing it inline, and it also refers there may be cross-browser problems. However, the post may be outdated (it is 3 years old, and one of the comments says even then it was 4 years old). Is there another more recent way of doing this?
I ask this because I try to keep my HTML and CSS completely separate.
However, is it maybe simpler, in terms of legibility and performance of the code, to simply specify the styles I want to change inline rather than on an external stylesheet?
Are there any best practices in regard to this matter?
When temporarily accessing or modifying an element's style using Javascript, there is no difference involved in whether that style was defined inline or in css - you will get the style that is applied by precedence and Javascript changes will override any declared style.
However, general best practice is to have a separate stylesheet (or maybe several if you intend to have conditional stylesheets for IE9 and below, or to split up lots of styles into manageable chunks)
This method is less complicated when it comes to debugging and changing styles in real time.
With external stylesheets you can change the entire site in seconds by dropping a new .css file in place. You can't do that with inline styles.
There are no benefits from inline-css except that it will be given more importance.
External css have the benefits of being cached.
However while rendering the below is the order followed.
Inline CSS styles are given more importance than to styles declaredd in <style></style> and styles declared in <style> is given more importance than to styles declared in external css. files.
Inline-css and even <style> is not preferred and is generally bad practice as extra bytes are transmitted over HTTP and they cannot be cached as external css files can be.
Styling using javascript should be just up to adding a class or removing a class or hiding and showing them, to improve the user experience.

Is the only way to change a style to do it per-element in JavaScript?

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/

Overriding containers CSS behavior

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.

Categories

Resources