DOM CSS Cross Browser Library - javascript

I normally work with jQuery, which takes away most of the cross browser pain (although not, unfortunately, all). However, it doesn't seem to have any support for manipulation of the CSS DOM, and this still seems to be a bit of a minefield - QuirksMode has some information.
Our application allows users to theme their site to some extend by generating a CSS stylesheet with the colours that they have selected. It's pretty straightforward, but I'd like to let them "preview" it by applying the changes directly to the CSS DOM, before having them save it back to the database and generating the CSS file.
Does anyone know of a library which will make cross browser CSS DOM maniuplation easier? Just so we're clear, I'm not trying to change the css rules on an element, or set of elements (like with $.css()), or to add/remove classes. I would like to modify the stylesheets directly.

I highly recommend the YUI stylesheet utility. I haven't seen any other libraries with as much functionality or as clean an interface.

Couldn't you just add or replace a <style> element in the main document's DOM, and fill it with the generated CSS?

Best and easiest way, is to create a .jsp .php or whatever you're using which accepts colour parameters, which in turn renders a .css output with colours replaced.
Use JavaScript to make a request with colour parameters and append the css script to the page.
It is possible to do it directly on the styleSheet object, though this will take more time and create more maintenance. Everytime you want to change your custom stylesheet you actually use for production, you will also have to change the preview version. Ergo discrepancies will ensue.
Just reuse the stylesheet template you're going to use for production anyways.

Maybe you should try something like:
document.styleSheets[0].disabled = true;
This disabled the first stylesheet of the current page. Maybe if you play around with it you can resolve your problem.

Related

Monkey patch external CSS

This is generic question, is it possible to monkey patch the CSS from link tag? I want to modify PrismJS library that have color and background and patch it to have --color and --background. Is something like this possible dynamically using JavaScript?
I would like this to be generic so no Service Worker, that will work only for local files that can be changed by modifying the file, I want to affect every possible url the same I'm patching JavaScript file. I can assume that the CSS selectors will always be the same.
The problem is that without the monkey patch I will need to maintain all themes that PrismJS have for different colors, I can write script that will create those styles for me but I want to know if there is a way to monkey patch. Also I can have single CSS file to be used instead of the PrismJS CSS, but I will lose different styles.
I have other options but right now I only want to know if monkey patch of external CSS is possible? I can't find anything like this.
I need to add that PrismJS themes are pretty simple they are just few selectors with colors. I'm not sure if they all have same selectors though.
EDIT:
To give you context I need this for jQuery Terminal to render text that user type (any programming language to be in color). I have one CSS that I have locally but without that file it don't work exactly the same (mainly there is lack of style for text selection that I would like to be in color, to have 100% working code as I want). The idea is to use same monkey patch I have but to use prism.css.

Verify that dynamically created CSS indeed loaded

I cannot find a way to identify whether the CSS, which was created dynamically via creating a <link> tag and then specifying the href attribute had indeed loaded.
Consider the following example:
var css = document.createElement("link");
css.href = "not-a-directory/not-a-css";
document.body.appendChild(css);
Some browsers (Firefox), will dispatch "onload" event even if the path doesn't designate an existing file, however, this would only happen if sandbox policies would have not been violated, if file existed. Opera, Google Chrome and Safari - all report the problem in some way, but I can't find a way to handle that in JavaScript.
I'm not interested in supporting MS Internet Explorer (the project will be deployed to embedded WebKit / Opera browsers), but if there is a crossplatform way - that's, of course, welcomed.
PS. "onerror" doesn't seem to trigger in any browser.
CLARIFICATION
Sorry, I had to provide more info. Now I'll try to fix that:
I prefer not to use other libraries (like jQuery), but if they solved it somehow, that's a valid solution, if I can take a look at how they did it.
The code will be deployed to either Opera or WebKit browsers on SmartTV (read it as severe size limitations + files may be required to load from file-system rather than from the net). This is why I can't use XMLHttpRequest.
If you can think of a way to test whether the text file exists given the path (think iframe, link - perhaps other elements?) That is a good option too.
Finally, after much struggle, here's what I did (but alternative solutions are welcome!):
Created a class with the name which is unlikely to happen in other CSS files, say:
.x29048723049820394 { color: #514159 }
and then created a div tag in the HTML page, where I wanted to test whether the CSS has indeed loaded. After creating a link tag (don't forget - you also need to specify the rel attribute, otherwise the style won't load), I set timer to wait for the div I just created to change color. After the color changed I'd assume that the CSS had loaded. Or if the time ran out, I'd give up, assuming that the CSS didn't load.
On the way I also discovered, that in case the CSS file is loaded from the file system, even the same directory as the original HTML, which requests it, you will run into security-related errors when either trying to access the innerHTML of the link or when trying to iterate through the style sheets of the document.
If you know a specific class name that should be loaded then you could use javascript to loop through all the style sheets and class names to see if it was loaded.
It is my understanding that there's no elegant and reliable way of detecting it, everything is more or less hacks.
Here's my hack off the top of my head:
$.ajax({
url: "/style.css",
dataType: "text",
success: function (cssString) {
// css file exists, and was loaded correctly.
$("head").append($("<style/>").text(cssString));
},
error: function (e) {
// css file did not exist, we can check status code with e.status (404 etc)
}
});
We basically load the css file as text using ajax and then attach the loaded data to the dom. This way we can reliably detect failures, but other than that it's a total hack. You most likely get a flash of unstyled content. I'm not sure I would use it, but I thought it might be fun to throw it out there along with all other hacks :-)

Using JQuery for CSS vs Stylesheet

Because I like keeping all source code in one file (per class), I decided to add all style and CSS using JQuery objects, i.e:
jquery : $('<div/>',
{
id:'Object',
css:{
height:'100%',
width:'69%',
color:'white',
fontWeight:'bold',
textAlign:'center',
backgroundColor:'#02297f',
marginLeft:'.5%',
'float':'left',
overflow:'auto',
borderRadius:'5px'
},
html : 'My JQuery Object'
}),
Now I know there is probably going to be some sort of performance impact, but my question is how much? Does anyone else do it this way? Am I overlooking a potential problem?
I like it this way because I can just use objects rather than having to cross examine a stylesheet and it keeps it better organized.
EDIT: This is for a Javascript application, not a web page. So disabling the Javascript will kill the webpage anyway.
There is certainly a performance impact. The script is only run when all the page is loaded, so it will give you problems when the page is first displayed.
Apart from that, you got no styling at all when you run a browser where javascript is disabled.
But most of all, it is a Bad Idea. CSS is for styling, for the looks of your page. HTML is for structure, and Javascript is for logic, interactivity. I think you shouldn't use the .css method at all. If you need to toggle styles in Javascript, use classes instead, which can then be styled using style sheets.
But this method of yours takes it a step further even. I think it's even worse than putting all the css in inline style attributes. I hope you are just asking this question to see how people respond. It must not be serious. :s
Your are doing it wrong.
CSS must stay in *.css files and Javascript in the *.js files.
There is this thing known as 3 layers of Web:
content ( HTML )
presentation ( CSS )
behavior ( JS )
First of all, yes, if you use JS to generate html and style it, this would have a huge impact on performance. But even ignoring it : you would make the code virtually unmaintainable.
If you want to have better organized stylesheets, then invest some time in expanding your knowledge in CSS, and looks at practices behind OOCSS.
Thats a TERRIBLE IDEA! Use instead http://xcss.antpaw.org/
I agree with the way you're doing it. I essentially use it myself. I am developing a html5 game and in that context what you are doing makes sense. In games, user events and system events constantly change the screen. You can only realistically deal with this via just-in-time styling. So using .css() is a great way to do this. I think in a game that sprites are so distinct that they require their own style object.

Proper way to render initially hidden HTML elements

I'm for years using something like this in my HTML for elements which should be hidden:
<div style="display: none"></div>
It's ok, but I can't stand in-line styles anymore.
Hiding elements programatically in JavaScript window.onload event is too late -- it will flash on the screen.
I can create CSS class 'hidden', but with browser's aggressive loading strategies (like in Opera) the block may appear for a second (before CSS is loaded).
Is there any better way?
As far as I know the class="hidden" method is the best and most commonly used. I suggest you use class="hidden".
"but with browser's aggressive loading strategies (like in Opera) the block may appear for a second (before CSS is loaded)."
I don't use Opera, but if any browser loaded the page before applying styles then a lot would look wrong, not just your hidden elements. I don't know of any browser doing this.
I have recently started using node objects, and I like this approach more and more. This way you don't have to use hidden HTML elements, you just place, for example, an anchor:
<a name="some-anchor" id="some-anchor-id" />
and then replace it with a created node. This way you won't have to worry about elements flickering on load, because there won't be any.
Depending on what the element is, it might be acceptable to generate and insert the element using javascript after the page has loaded (rather than hiding it after page load). Just a thought, although it wouldn't degrade gracefully for users without javascript enabled...
You could add to the hidden style a fixed position which would bring it out of a browsers window. This may be a solution to avoid having the div blink in Opera.
For example:
.super_hide{
position:fixed;
top:-1000px; /* you would need to know how height the content is or put something huge*/
}
Hoping this will help!
If you have a HTML only page those elements would be shown?
These elements are shown to screen readers by default, that's not very nice or accessible is it?
If you have HTML+CSS only page you can't unhide these elements, then there's no point in them apart from black hat SEO tricks.
If you have a HTML+CSS+JS page then there is value in have them.
There is only value in having them when you have JS enabled. This means they should _exist in the javascript
Use javascript to create these elements and inject them in the DOM.
if your build your website from the ground up using HTML, HTML+CSS, HTML+CSS+JS then you would realize they belong in your javascript code. Feel free to read more about Progressive Enhancement
You could define the class in of the page. It's slightly cleaner than inline, but you would have to have that single class definition on all pages. But then again, I'd try to use a single dynamic footer/header anyway..

Is there a way to create your own HTML element?

Is there a way to create your own HTML element? I want to make a specially designed check box.
I imagine such a thing would be done in JavaScript. Something akin to document.createHTMLElement but the ability to design your own element (and tag).
No, there isn't.
The HTML elements are limited to what the browser will handle. That is to say, if you created a custom firefox plugin, and then had it handle your special tag, then you "could" do it, for varying interpretations of "doing it". A list of all elements for a particular version of HTML may be found here: http://www.w3.org/TR/html4/index/elements.html
Probably, however, you don't actually want to. If you want to "combine" several existing elements in such a way as they operate together, then you can do that very JavaScript. For example, if you'd like a checkbox to, when clicked, show a dropdown list somewhere, populated with various things, you may do that.
Perhaps you may like to elaborate on what you actually want to achieve, and we can help further.
Yes, you can create your own tags. You have to create a Schema and import it on your page, and write a JavaScript layer to convert your new tags into existing HTML tags.
An example is fbml (Facebook Markup Language), which includes a schema and a JavaScript layer that Facebook wrote. See this: Open Graph protocol.
Using it you can make a like button really easily:
<fb:like href="http://developers.facebook.com/" width="450" height="80"/>
The easiest way would be probably to write a plugin say in Jquery (or Dojo, MooTools, pick one).
In case of jQuery you can find some plugins here http://plugins.jquery.com/ and use them as a sample.
You need to write own doctype or/and use own namespace to do this.
http://msdn.microsoft.com/en-us/magazine/cc301515.aspx
No, there is not. Moreover it is not allowed in HTML5.
Take a look at Ample SDK JavaScript GUI library that enables any custom elements or event namespaces client-side (this way XUL for example was implemented there) without interferring with the rules of HTML5.
Take a look into for example how XUL scale element implemented: http://github.com/clientside/amplesdk/blob/master/ample/languages/xul/elements/scale.js and its default stylesheet: http://github.com/clientside/amplesdk/blob/master/ample/languages/xul/themes/default/input.css
It's a valid question, but I think the name of the game from the UI side is progressive markup. Build out valid w3 compliant tags and then style them appropriately with javascript (in my case Jquery or Dojo) and CSS. A well-written block of CSS can be reused over and over (my favorite case is Jquery UI with themeroller) and style nearly any element on the page with just a one or two-word addition to the class declaration.
Here's some good Jquery/Javascript/CSS solutions that are relatively simple:
http://www.filamentgroup.com/examples/customInput/
http://aaronweyenberg.com/90/pretty-checkboxes-with-jquery
http://www.protofunc.com/scripts/jquery/checkbox-radiobutton/
Here's the spec for the upcoming (and promising) JqueryUI update for form elements:http://wiki.jqueryui.com/Checkbox
If you needed to validate input, this is an easy way to get inline validation with a single class or id tag: http://www.position-absolute.com/articles/jquery-form-validator-because-form-validation-is-a-mess/
Ok, so my solution isn't a 10 character, one line solution. However, Jquery Code aside, each individual tag wouldn't be much more than:
<input type="checkbox" id="theid">
So, while there would be a medium chunk of Jquery code, the individual elements would be very small, which is important if you're repeating it 250 times (programmatically) as my last project required. It's easy to code, degrades well, validates well, and because progressive markup would be on the user's end, have virtually no cost on the server end.
My current project is in Symfony--not my choice--which uses complex, bulky server-side tags to render form elements, validate, do javascript onclick, style, etc. This seems like what you were asking for at first....and let me tell you, it's CLUNKY. One tag to call a link can be 10 lines of code long! After being forced to do it, I'm not a fan.
Hm. The first thought is that you could create your own element and do a transformation with XSLT to the valid HTML then.
With the emergence of the emerging W3 Web Components standard, specifically the Custom Elements spec, you can now create your own custom HTML elements and register them with the parser with the document.register() DOM method.
X-Tag is a helpful sugar library, developed by Mozilla, that makes it even easier to work with Web Components, have a look: X-Tags.org

Categories