Using Javascript in CSS

Is it possible to use Javascript inside CSS?

If it is, can you give a simple example?

Answers:

Answer

IE and Firefox both contain ways to execute JavaScript from CSS. As Paolo mentions, one way in IE is the expression technique, but there's also the more obscure HTC behavior, in which a seperate XML that contains your script is loaded via CSS. A similar technique for Firefox exists, using XBL. These techniques don't exectue JavaScript from CSS directly, but the effect is the same.

HTC with IE

Use a CSS rule like so:

body {
  behavior:url(script.htc);
}

and within that script.htc file have something like:

<PUBLIC:COMPONENT TAGNAME="xss">
   <PUBLIC:ATTACH EVENT="ondocumentready" ONEVENT="main()" LITERALCONTENT="false"/>
</PUBLIC:COMPONENT>
<SCRIPT>
   function main() 
   {
     alert("HTC script executed.");
   }
</SCRIPT>

The HTC file executes the main() function on the event ondocumentready (referring to the HTC document's readiness.)

XBL with Firefox

Firefox supports a similar XML-script-executing hack, using XBL.

Use a CSS rule like so:

body {
  -moz-binding: url(script.xml#mycode);
}

and within your script.xml:

<?xml version="1.0"?>
<bindings xmlns="http://www.mozilla.org/xbl" xmlns:html="http://www.w3.org/1999/xhtml">

<binding id="mycode">
  <implementation>
    <constructor>
      alert("XBL script executed.");
    </constructor>
  </implementation>
</binding>

</bindings>

All of the code within the constructor tag will be executed (a good idea to wrap code in a CDATA section.)

In both techniques, the code doesn't execute unless the CSS selector matches an element within the document. By using something like body, it will execute immediately on page load.

Answer

I think what you may be thinking of is expressions or "dynamic properties", which are only supported by IE and let you set a property to the result of a javascript expression. Example:

width:expression(document.body.clientWidth > 800? "800px": "auto" );

This code makes IE emulate the max-width property it doesn't support.

All things considered, however, avoid using these. They are a bad, bad thing.

Answer

To facilitate potentially solving your problem given the information you've provided, I'm going to assume you're seeking dynamic CSS. If this is the case, you can use a server-side scripting language to do so. For example (and I absolutely love doing things like this):

styles.css.php:

body
 {
margin: 0px;
font-family: Verdana;
background-color: #cccccc;
background-image: url('<?php
echo 'images/flag_bg/' . $user_country . '.png';
?>');
 }

This would set the background image to whatever was stored in the $user_country variable. This is only one example of dynamic CSS; there are virtually limitless possibilities when combining CSS and server-side code. Another case would be doing something like allowing the user to create a custom theme, storing it in a database, and then using PHP to set various properties, like so:

user_theme.css.php:

body
 {
background-color: <?php echo $user_theme['BG_COLOR']; ?>;
color: <?php echo $user_theme['COLOR']; ?>;
font-family: <?php echo $user_theme['FONT']; ?>;
 }

#panel
 {
font-size: <?php echo $user_theme['FONT_SIZE']; ?>;
background-image: <?php echo $user_theme['PANEL_BG']; ?>;
 }

Once again, though, this is merely an off-the-top-of-the-head example; harnessing the power of dynamic CSS via server-side scripting can lead to some pretty incredible stuff.

Answer

IE supports CSS expressions:

width:expression(document.body.clientWidth > 955 ? "955px": "100%" );

but they are not standard and are not portable across browsers. Avoid them if possible. They are deprecated since IE8.

Answer

Not in any conventional sense of the phrase "inside CSS."

Answer

I ran into a similar problem and have developed two standalone tools to accomplish this:

  • CjsSS.js is a Vanilla Javascript tool (so no external dependencies) that supports back to IE6.

  • ngCss is an Angular Module+Filter+Factory (aka: plugin) that supports Angular 1.2+ (so back to IE8)

Both of these tool sets allow you to do this in a STYLE tag or within an external *.css file:

/*<script src='some.js'></script>
<script>
    var mainColor = "#cccccc";
</script>*/

BODY {
    color: /*{{mainColor}}*/;
}

And this in your on-page style attributes:

<div style="color: {{mainColor}}" cjsss="#sourceCSS">blah</div>

or

<div style="color: {{mainColor}}" ng-css="sourceCSS">blah</div>

NOTE: In ngCss, you could also do $scope.mainColor in place of var mainColor

By default, the Javascript is executed in a sandboxed IFRAME, but since you author your own CSS and host it on your own server (just like your *.js files) then XSS isn't an issue. But the sandbox provides that much more security and peace of mind.

CjsSS.js and ngCss fall somewhere in-between the other tools around to accomplish similar tasks:

  • LESS, SASS and Stylus are all Preprocessors only and require you to learn a new language and mangle your CSS. Basically they extended CSS with new language features. All are also limited to plugins developed for each platform while CjsSS.js and ngCss both allow you to include any Javascript library via <script src='blah.js'></script> straight in your CSS!

  • AbsurdJS saw the same problems and went the exact opposite direction of the Preprocessors above; rather than extending CSS, AbsurdJS created a Javascript library to generate CSS.

CjsSS.js and ngCss took the middle ground; you already know CSS, you already know Javascript, so just let them work together in a simple, intuitive way.

Answer

This turns out to be a very interesting question. With over a hundred properties being set, you'd think that you'd be allowed to type .clickable { onclick : "alert('hi!');" ; } in your CSS, and it'd work. It's intuitive, it makes so much sense. This would be amazingly useful in monkey-patching dynamically-generated massive UIs.

The problem:
The CSS police, in their infinite wisdom, have drawn a Chinese wall between presentation and behavior. Any HTML properly labeled on-whatever is intentionally not supported by CSS. (Full Properties Table)

The best way around this is to use jQuery, which sets up an interpreted engine in the background to execute what you were trying to do with the CSS anyway. See this page: Add Javascript Onclick To .css File.

Good luck.

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us Javascript

©2020 All rights reserved.