Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 14 of 14
  1. #1
    Regular Coder
    Join Date
    Jan 2006
    Posts
    377
    Thanks
    8
    Thanked 1 Time in 1 Post

    Create virtual styles?

    Hi,

    I have a form where I let the admin CSS values like color, border width etc.

    I also have a .js file where I gather these form field values and apply them dynamically to a test object with id="testblock".

    I saw that it is possible to apply a whole class to an object like

    Code:
    var testblock = documentGetElementByID('testblock');
    testblock.className = "myclass";

    However, I don't have "myclass" defined. I can't pre-define it as my values are generated on-the-fly.

    Question, can I crate a class somewhere based on user's selections and apply it to the element?

  • #2
    Senior Coder Arbitrator's Avatar
    Join Date
    Mar 2006
    Location
    Splendora, Texas, United States of America
    Posts
    3,300
    Thanks
    28
    Thanked 275 Times in 269 Posts
    Quote Originally Posted by guvenck View Post
    Code:
    var testblock = documentGetElementByID('testblock');
    testblock.className = "myclass";
    I assume that you meant document.getElementById("testblock").

    Quote Originally Posted by guvenck View Post
    However, I don't have "myclass" defined. I can't pre-define it as my values are generated on-the-fly.

    Question, can I crate a class somewhere based on user's selections and apply it to the element?
    Yes, you can.

    Code:
    var CSS; /* Fill this variable with the CSS declarations. */
    var sheet = document.styleSheets[0];
    sheet.insertRule("myclass { " + CSS + " }", sheet.cssRules.length);
    According to W3C DOM Compatibility - CSS, Internet Explorer uses a proprietary method called addRule() though.
    For every complex problem, there is an answer that is clear, simple, and wrong.

  • #3
    Regular Coder
    Join Date
    Jan 2006
    Posts
    377
    Thanks
    8
    Thanked 1 Time in 1 Post
    Thanks for the enlightement. Sorry for the typo.

    I guess the styleSheets[0] is the first stylesheet in the page and according to your code, we access it dynamically.

    I am going to insert several classes, in some cases where multilevel menus are involved, it gets up to 20 classes for a single menu. Is there an easy way to do that?

  • #4
    Senior Coder Arbitrator's Avatar
    Join Date
    Mar 2006
    Location
    Splendora, Texas, United States of America
    Posts
    3,300
    Thanks
    28
    Thanked 275 Times in 269 Posts
    Quote Originally Posted by guvenck View Post
    Thanks for the enlightement. Sorry for the typo.

    I guess the styleSheets[0] is the first stylesheet in the page and according to your code, we access it dynamically.

    I am going to insert several classes, in some cases where multilevel menus are involved, it gets up to 20 classes for a single menu. Is there an easy way to do that?
    You’d have to create all twenty classes independently unless they follow the some pattern (in which case you would use a loop). If they reference identical declarations, then you could modify the mentioned code as shown below.

    Code:
    var CSS; /* Fill this variable with the CSS declarations. */
    var sheet = document.styleSheets[0];
    sheet.insertRule("class1, class2, class3 /* etc */ { " + CSS + " }", sheet.cssRules.length);
    For every complex problem, there is an answer that is clear, simple, and wrong.

  • #5
    Regular Coder
    Join Date
    Jan 2006
    Posts
    377
    Thanks
    8
    Thanked 1 Time in 1 Post
    Got it. Unfortunately, they don't follow the same pattern and I have created them seperately.

    One more problem: I have to keep the styles not in a file, but between the <head></head> tags. What would the solution be in this case?

    And, I met some nice piece of code here, seems to take care of both browsers:

    http://www.hunlock.com/blogs/Totally...ript#quickIDX0

  • #6
    Senior Coder Arbitrator's Avatar
    Join Date
    Mar 2006
    Location
    Splendora, Texas, United States of America
    Posts
    3,300
    Thanks
    28
    Thanked 275 Times in 269 Posts
    Quote Originally Posted by guvenck View Post
    One more problem: I have to keep the styles not in a file, but between the <head></head> tags. What would the solution be in this case?
    You can create an embedded style sheet manually or add one via the script. An example of the latter is shown below.

    Code:
    var sheet = document.createElement("style");
    sheet.setAttribute("type", "text/css");
    document.getElementsByTagName("head")[0].appendChild(sheet);
    Now that I think about it, it may be easier to do this and then insert all of the CSS rules as a single string.

    Code:
    var sheet = document.createElement("style");
    var rules = document.createTextNode("\
    	class1 { declarations }\
    	class2 { declarations }\
    	class3 { declarations }\
    	/* etc */");
    sheet.setAttribute("type", "text/css");
    sheet.appendChild(rules);
    document.getElementsByTagName("head")[0].appendChild(sheet);
    For every complex problem, there is an answer that is clear, simple, and wrong.

  • #7
    Regular Coder
    Join Date
    Jan 2006
    Posts
    377
    Thanks
    8
    Thanked 1 Time in 1 Post
    Many thanks, I managed to get a solution using insertRule. However, my clients are going to use Internet Explorer mostly (and unfortunately) and I need to provide them with a solution too.

    Can I write a function that finds out visitors browser and runs addRule for IE and insertRule for FF?

  • #8
    Senior Coder Arbitrator's Avatar
    Join Date
    Mar 2006
    Location
    Splendora, Texas, United States of America
    Posts
    3,300
    Thanks
    28
    Thanked 275 Times in 269 Posts
    Quote Originally Posted by guvenck View Post
    Can I write a function that finds out visitors browser and runs addRule for IE and insertRule for FF?
    It’s better to test for browser support than the browser itself. Below are shown two methods; the first uses separate scripts and second uses a single script.

    Code:
    <script type="application/ecmascript">
    	var sheet = document.styleSheets[0];
    	sheet.insertRule("html { background: lime; }", sheet.cssRules.length);
    </script>
    <!--[if IE]>
    	<script type="text/javascript">
    		document.styleSheets[0].addRule("html", "background: lime;");
    	</script>
    <![endif]-->
    Code:
    <script type="text/javascript">
    	var sheet = document.styleSheets[0];
    	if (sheet.insertRule) {
    		sheet.insertRule("html { background: lime; }", sheet.cssRules.length);
    	}
    	else {
    		sheet.addRule("html", "background: lime;");
    	}
    </script>
    Last edited by Arbitrator; 06-21-2007 at 07:01 PM. Reason: I removed some redundancy in the code.
    For every complex problem, there is an answer that is clear, simple, and wrong.

  • #9
    New to the CF scene
    Join Date
    May 2006
    Posts
    5
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Hi there, is there any alternative to the addRule method? It is not compatible with pseudo classes

    This works:

    Code:
    document.styleSheets[0].addRule("body", "display:none");
    The following won't work:

    Code:
    document.styleSheets[0].addRule("body>table:nth-of-type(2)", "display:none");
    You get an "Invalid argument" error message.
    Thanks.

  • #10
    New to the CF scene
    Join Date
    May 2006
    Posts
    5
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Does some one know?

  • #11
    Senior Coder Arbitrator's Avatar
    Join Date
    Mar 2006
    Location
    Splendora, Texas, United States of America
    Posts
    3,300
    Thanks
    28
    Thanked 275 Times in 269 Posts
    Quote Originally Posted by calande View Post
    Hi there, is there any alternative to the addRule method? It is not compatible with pseudo classes

    This works:

    Code:
    document.styleSheets[0].addRule("body", "display:none");
    The following won't work:

    Code:
    document.styleSheets[0].addRule("body>table:nth-of-type(2)", "display:none");
    You get an "Invalid argument" error message.
    The addRule method is proprietary to Microsoft [1] and only works in their Windows Internet Explorer browser. That browser doesn't support the nth-of-type pseudo-class; presumably, that explains why you're getting the “Invalid argument” error message.

    For browsers that support the DOM2 Style specification, you can use the insertRule method [2] instead:

    Code:
    document.styleSheets.item(0).insertRule("body > table:nth-of-type(2) { display: none; }", document.styleSheets.item(0).cssRules.length);
    The code above will append the CSS rule to the end of the first style sheet (if there is one).

    You also need to make sure that the browsers that you're targeting support the nth-of-type pseudo-class; those appear to be Opera 9.5+ [3] and Safari 3.1+ [4]. Mozilla Firefox 3.5 Beta also supports it [5].

    1. http://msdn.microsoft.com/en-us/libr...00_altSelector
    2. http://www.w3.org/TR/DOM-Level-2-Sty...eet-insertRule
    3. http://www.opera.com/docs/specs/css/
    4. http://www.css3.info/safari-31-pushe...pport-forward/
    5. https://developer.mozilla.org/en/CSS/%3anth-of-type
    For every complex problem, there is an answer that is clear, simple, and wrong.

  • #12
    New to the CF scene
    Join Date
    May 2006
    Posts
    5
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Thanks. But one thing is strange: If I set the nth-of-type pseudo-class using simple <style> tags directly inside an HTML file, it works properly in IE 8. So I think IE8 supports it, no? Maybe there's another way to inject CSS rules using Javascript?

  • #13
    Senior Coder Arbitrator's Avatar
    Join Date
    Mar 2006
    Location
    Splendora, Texas, United States of America
    Posts
    3,300
    Thanks
    28
    Thanked 275 Times in 269 Posts
    Quote Originally Posted by calande View Post
    Thanks. But one thing is strange: If I set the nth-of-type pseudo-class using simple <style> tags directly inside an HTML file, it works properly in IE 8. So I think IE8 supports it, no?
    I just wrote a test case [1] that seems to indicate otherwise. I tested the latest release versions of Mozilla Firefox, Opera, Safari, and Windows Internet Explorer; only Opera and Safari passed the test. (And, yes, I used WIE8.)

    [1] http://www.jsgp.us/demos/CF116737.html

    Code:
    <!doctype html public "-//W3C//DTD HTML 4.01//EN">
    
    <html lang="en-Latn">
    	<head>
    
    		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    		<title>Demo for CodingForums.com Thread 116737</title>
    		<style type="text/css" media="all">
    			* { margin: 0; padding: 0; }
    			html { background: white; font: 1em/1 sans-serif; }
    			body { margin: 1em 0.5em; }
    			p { margin: 0.5em; padding: 0.5em; background: red; color: white; }
    			p:first-child + p,
    			p:first-child + p + p + p,
    			p:first-child + p + p + p + p + p,
    			p:first-child + p + p + p + p + p + p + p,
    			p:first-child + p + p + p + p + p + p + p + p + p { background: lime; color: black; }
    			p:nth-of-type(odd) { background: lime; color: black; }
    		</style>
    
    	</head>
    	<body>
    
    		<p>This paragraph should have a lime&#x2010;colored background.</p>
    		<p>This paragraph should have a lime&#x2010;colored background.</p>
    		<p>This paragraph should have a lime&#x2010;colored background.</p>
    		<p>This paragraph should have a lime&#x2010;colored background.</p>
    		<p>This paragraph should have a lime&#x2010;colored background.</p>
    		<p>This paragraph should have a lime&#x2010;colored background.</p>
    		<p>This paragraph should have a lime&#x2010;colored background.</p>
    		<p>This paragraph should have a lime&#x2010;colored background.</p>
    		<p>This paragraph should have a lime&#x2010;colored background.</p>
    		<p>This paragraph should have a lime&#x2010;colored background.</p>
    
    	</body>
    </html>
    Last edited by Arbitrator; 04-24-2009 at 09:02 AM. Reason: I removed extraneous tabs in the style sheet.
    For every complex problem, there is an answer that is clear, simple, and wrong.

  • #14
    New to the CF scene
    Join Date
    May 2006
    Posts
    5
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Interesting... The above doesn't work in IE8, however they have already implemented the :first-child pseudo-class...Oh, well...Thanks anyway, I'll wait for MS to complete the CSS3 implementation of their browser


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •