Changing CSS Rules using JavaScript or jQuery - javascript

Initial Research
I am aware of using .css() to get and set the CSS rules of a particular element. I have seen a website with this CSS:
body, table td, select {
font-family: Arial Unicode MS, Arial, sans-serif;
font-size: small;
}
I never liked Arial Unicode as a font. Well, that was my personal feel. So, I would use Chrome's Style Inspector to edit the Arial Unicode MS to Segoe UI or something which I like. Is there anyway, other than using the following to achieve the same?
Case I
$("body, table td, select").css("font-family", "Segoe UI");
Recursive, performance intensive.
Doesn't work when things are loaded on the fly.
Case II
$('<style>body, table td, select {font-famnily: "Segoe UI";}</style>')
.appendTo("head");
Any other better method than this?
Creates a lot of <style> tags!

Ok, if:
Personal Preference
Then use user styles CSS. According to priority, user styles takes precedence above all other styles. Next comes inline-styles, then !important styles, then specificity, then default browser styles. If it's just for personal preference, pack-up a custom CSS with you and a browser that supports it.
You are the developer
Then don't do this in JavaScript or user scripts. Go down to the problem and change those styles! You are just making the browser work more by actually making it parse stuff you don't want. Since you have access to the code, change the styles instead.
However, since your site could be a public site, style it like genericly for everyone. It's not only you that's viewing the site.
Not the developer:
The best way I can think of (and already did this before*) is to remove external stylesheets from the page and replace them with modded versions of your own liking. That is taking a copy of the original CSS file, change what needs to be changed, and then load it via JS by creating a <link> to that external file, or load the contents via AJAX and put them in a <style>. However, this approach is riddled with obstacles. <link> does not have an onload event so you won't know the external CSS was loaded (there are crafty workarounds though) and AJAXing CSS contents imply that your CSS is in the same domain or the browser and server supports CORS.
Another way you can do it is to have JS peek into loaded stylesheets and modify their contents. This is a more JS intensive work since JS looks for your definition to change in a pile of CSS declarations. This is a safer bet, however, I believe not all browsers can traverse CSS styles or at least do it differently across browsers. Also, if you got a large stylesheet, you'd be parsing it every time.
As you said, .css() would be recursive. True, because it applies inline styles to each affected element. This is good in a sense that inline styles are higher up in the priority so whatever is placed using .css(), you are almost sure that they will take effect. However, it's more work intensive since it involves the DOM now.
* The library I created does not remove existing styles, it just loads and unloads predefined styles declared using it's API

Have a look at:
Quirksmode: Change CSS
Totally Pwn CSS with Javascript
Is the only way to change a style to do it per-element in JavaScript? (possible duplicate)
I'm afraid there is no library for that, I really would like to see one...

Related

What are the disadvantages of using ng-style?

I have used ng-style in code, but my manager said not to use ng-style since it will create problem.
I still don't know what problem he faced before and I would like to know what are the disadvantages of using ng-style?
You cannot reuse the styles anywhere else.
The html markup of the page becomes cumbersome, and tough to parse for the naked eye.
Since, they are not stored at a single place, they are tough to be edited
This approach does not provide consistency across your application. The inline styles on elements can cause a major headache.
It does not provide you with the browser cache advantage. The files are repeatedly downloaded by the client on every request. Instead, consider using External style sheets.
Inline styles take precedence over page-level style declarations and external style sheets. So you could accidentally override styles that you did not intend.
It's impossible to style pseudo-elements and -classes with inline styles. For example, with external and internal style sheets, you can style the visited, hover, active, and link color of an anchor tag.
Please refer
Inline style disadvantages
Other link

Runtime modification of Chrome extension resident stylesheet

We're writing a Chrome extension that creates information pop-ups. We would like to be able to toggle the font-size at the user's request at runtime.
The strange thing is, the stylesheet, which is included in the Chrome extension manifest, does not show up in the page head list of stylesheets.
I presume the stylesheet must be referenced using a chrome.extension.getStylesheet or some such operator.
Once we have an object pointer to the relevant stylesheet, it is our intent to adjust the font-size of the corresponding element.
Any help?
Sam
The stylesheet injected through the manifest file cannot be edited via an API.
If you want to dynamically change the value, use chrome.tabs.insertCSS (see optionally inject content scripts for a breakdown of the several ways to call insertCSS in time) or chrome.declarativeContent.RequestContentScript. The latter does not accept arbitrary code yet. Luckily, the number of sensible font sizes are limited, so you could hard-code different stylesheets for (e.g.) font sizes 7 up to 40 and be done.
If the stylesheet is only useful for a few pages, and the value is dynamically calculated in a content script, then creating and injecting a <style> is also a good option.
If you use exactly the same CSS selector, then the last stylesheet will always take precedence over the previous one (if the selectors are different, then CSS specificity will determine what happens).

Disabling user agent style sheet

Is it possible to embed some code in Javascript or CSS for a particular webpage to disable (not load) the user agent style sheet that comes with the browser? I know that I can override it by CSS, but that creates lots of overriden specifications, and that seems to highly affect the CPU usage when browsing the page. Especially, I did something like *{margin:0; padding: 0}, which seems to be expensive for rendering (particularly the * selector is expensive). So, I do not want to heavily override the user agent style sheet but rather disable that in the first place if possible. Is this possible? If so, how? I am especially using Google Chrome, but would expect a cross browser way if possible.
I wonder whether there is a way to disable user agent style sheet directly in JavaScript. There does not seem to be any direct way, since document.styleSheets does not contain the user agent style sheet. On the other hand, Firefox Web Developer Extension has, in the CSS menu, an option for disabling Browser Default Stylesheet.
Anyway, there is a markup way, though I’m not sure whether you like its implications. To start with, it does not work on IE 8 and earlier (they’ll show just XML markup, not the formatted content). But modern browsers can handle this:
Use XHTML markup but do not include the xmlns attribute in the html tag.
Serve the document as application/xml.
For elements that should be handled with their HTML semantics (e.g., input creates an input box), use the xmlns="http://www.w3.org/1999/xhtml" attribute on the element or an enclosing element.
Simple demo.
This means that outside the effect of xmlns attributes, all markup is taken as constituting pure, meaning-free, formatting-free (all elements are inline) elements. They can be styled in your stylesheet, though.
But this way, you cannot both keep the HTML cake and eat it. That is, you cannot get HTML functionality (for form fields, links, etc.) without having user agent stylesheet being applied to them.
Use a "reset stylesheet" - this one is good: http://html5boilerplate.com/
It's not possible. Just create a css file called by most of the people 'reset.css' which includes all the css code used to override user agent's styles
You can use something like reset css (http://www.cssreset.com/) to reset all browser styles..
or, what i prefer, use normalize css (http://necolas.github.com/normalize.css/) that normalizes the css without resetting all styles like list styles on ul, li etc. (reset.css would do that)

dynamically load css approaches

I have long known that you can load style rules into a page dynamically by using addRule() and insertRule(), depending on whether it is IE or a standards compliant browser. But I just discovered that on Chrome, a much more generally-useful (for me) approach works just fine: create a style element, add a texnode to it with arbitrary css text (it could be the contents of a css file), then add that to the document. You can also remove it by removing that style node from the document. For instance this function works fine when I send it the string "div {background-color: red; }\n p {font-family: georgia; }":
var applyCss = function (cssString) {
var scriptNode = document.createElement('style');
scriptNode.appendChild(document.createTextNode(cssString));
document.getElementsByTagName('head')[0].appendChild(scriptNode);
return scriptNode;
};
While I understand the benefits of doing it on a rule basis in some scenarios, this shortcut (which is kind of analogous to using innerHTML instead of building elements part by part using DOM techniques) would be particularly useful to me in a lot of situations if I can count on it working.
Is it consistently supported? Is there any downside to this approach? I'm particularly curious because I've never seen this approach suggested anywhere.
The primary reason you wouldn't see this approach mentioned or suggested anywhere is largely because it's unnecessary. Instead of constantly trying to edit style elements, you should have a set of classes that you add and remove from elements dynamically.
In my experience, dynamically adding a style element with text works cross browser. So far I haven't found a browser that doesn't work with something like:
//jQuery for brevity
$('<style>p{margin:0}</style>').appendTo('head');
The only situation I've ever needed this in was for adding a large set of very specific styles for usage with a bookmarklet. Otherwise, I'll dynamically add a stylesheet:
$('<link rel="stylesheet" type="text/css" href="path/to/stylesheet.css />').appendTo('head');
But really, stylesheets should already exist within the HTML.
Use YepNope lib, it will do the dirty stuff for you. And it's only 1.7kb when gzipped and minified.

Why not use inline CSS if all the HTML+CSS is generated at runtime by javascript and no developer will need to work with css and html?

The only reasons I see on the internet to not to use inline-css is because of the separation of html and css & management, but if this is not a problem in my case I don't care I will use.
Another pro I can say is this: imagine you want to load a widget made by another user, you will only need to load 1 file, the javascript and not the css.
But it might have other problems?
thanks
If you read your question again, you have answered it yourself. There is a reason for the "separation" of html and CSS. Because at some point in time, you will eventually want to change the look of what you have coded up. These are the times when having a separate CSS file would be very helpful so you are only ever making changes in one place and not throughout your application.
EDIT
Another usefulness of having the CSS separate is the caching. Most of the modern browsers cache the CSS files. This means there are less round-trips to the server and quicker response times. I'm not sure if same is the case for JavaScript, because JavaScript files would be cached, but the client browser will have to execute the code every time it loads.
I think this is a good question that is worth exploring. I don't think there is a performance or standards-based argument for not using inline CSS - it works perfectly well - the only (though considerable) argument for separated CSS is for maintainability / readability. And so if you are generating CSS from JavaScript, generating it inline is just as sound as any other way.
In fact, DOM APIs in general expose much simpler methods for assigning styles directly to elements ( https://developer.mozilla.org/en/DOM/element.style ) than for creating new stylesheets. Therefore almost all JavaScript libraries, like jQuery, when they have to manipulate styles they do it by adding inline styles to an element.
Having said that, I have never before seen a situation where the mark-up and styling for a whole page was generated with JavaScript. I would expect this to be rather inefficient. I can see that if you have a web application where all content is pulled in through Ajax (a perfectly good solution) then you might write a fair bit of the mark-up with JavaScript, but still it would be better/more efficient to load most of the surrounding mark-up for your content in the initial page load, and then use JavaScript to swap out content within existing elements.
In any case, I would recommend that you keep most of your CSS in an external stylesheet with relevant classes already defined, so that all your JavaScript does is create elements with the correct class. This would have a performance advantage and would also mean that all your style information was located in one place, and is separate from your JavaScript, which would make your code easier to maintain.
It's OK to use inline css. (in this specifice case)

Categories

Resources