5

For example, I'd like to do something like the following:

.myRedPath {
    fillcolor: red;
}

...

<v:path class="myRedPath" v="..."/>

to fill my paths with a red color. Is this possible with the color and opacity of the fill and stroke attributes for VML elements? If so, how?

Josh Knauer
  • 1,744
  • 2
  • 17
  • 29
  • Why use VML when you can use Canvas? – Josh Smith Dec 29 '11 at 02:53
  • 3
    Probably for backwards compatibility. Although I would suggest using Raphael instead since it abstracts away the browser incompatibilities. – Hyangelo Jan 05 '12 at 16:23
  • Yes, unfortunately I have to support older versions of IE. Raphael is great, but one of the things that it seems to be missing is that you can only style shapes explicitly, not through CSS. I'm assuming the answer to this questions is "no you can't do that", but I'm hopeful that I'm just missing something :) – Josh Knauer Jan 05 '12 at 17:13

3 Answers3

3

As mentioned in other answers, you may use DHMTL behaviors to apply any style specified in your style sheet to your VML element as behaviors are supported from IE5 to IE9.

Start by creating a HTC file, eg: vmlcss.htc:

<PUBLIC:COMPONENT>
<PUBLIC:ATTACH EVENT="onpropertychange" ONEVENT="onpropertychange()" />
<PUBLIC:METHOD NAME="refresh" />
<SCRIPT LANGUAGE="JScript">

    function onpropertychange()
    {
        if (event.propertyName == "className")
        {
            refresh();
        }
    }

    function refresh()
    {
        // Set any VML attribute you may define in your stylesheet
        element.fillcolor = element.currentStyle["fillcolor"];
        element.strokecolor = element.currentStyle["strokecolor"];
        // etc.
    }

    refresh();

</SCRIPT>
</PUBLIC:COMPONENT>

Then apply it to your VML elements. For your particular example, you would use:

<style>
    v\:path
    {
        behavior: url(vmlcss.htc);
    }
</style>

Finally, specify the styles as shown in your example:

.myRedPath
{
    fillcolor: red;
    strokecolor: yellow;
}

You may want to modify the behavior file to add support for all VML attributes.

One could use such a technique to write a library that draws shapes using VML or SVG (depending on the browser support) and allows styling through CSS. Support for SVG styles could then be added to the VML objects using such a behavior file by mapping each SVG style to the corresponding VML attributes.

Gyum Fox
  • 3,287
  • 2
  • 41
  • 71
2

In IE7, you can do following:

vml\:polyline
{
  strokecolor: expression(this.strokecolor = "red");
  fillcolor: expression(this.fillcolor = "green");
}

But it doesn't work in IE8+ Standards mode, so not really that much useful.

1

VML uses attributes instead of CSS properties, so the only way to reference them in a style sheet is to add another behavior URL which references a htc which sets attribute values. Otherwise, use a HTML element to wrap the VML element and add the background color to it:

<!doctype html>
<html xmlns:v xmlns:svg='http://www.w3.org/2000/svg'>
  <head>
    <meta charset="UTF-8">
    <title>Lightbox Simple</title>
    <style type="text/css">
    /* Hide scrollbars */
    /*html, body { overflow: hidden; }*/

    /*modal input*/
    .trigger { display:inline-block; }

    /* Hide modal transparency */
    .dialog, .film { position:absolute; left:-7777px; z-index:2; }

    /* modal output */
    a.trigger:hover .dialog { display: block; left:50%; top:50%; width:500px; border: 1px solid #fff; }
    a.trigger:hover .film { left: -3333px; top:-3333px; width:7777px; height:7777px; opacity: .7; background-color: #000; z-index: 3;}

    /* modal content */
    .visible { display: inline-block; background-color: #999; position:absolute; width: 200px; z-index: 4;}

    /* modal off switch */
    .closer { z-index:4; position:absolute; top:0; right:20px; display:block; background-color: #fff; color: #fff; width:0; }

    .placeholder { position:absolute; top:0; left:0; }
    @media,
        {
        v\:rect,v\:fill { behavior:url(#default#VML);}

        .vml_bg
        {
        position:absolute;
        left:0;
        top:0;
        width:100%;
        height:100%;
        }

        a.trigger:hover .film { width: 0; }

        .vml_wrap {
        position:absolute;
        left:0;
        top:0;
        width:0;
        height:0;
        display:inline-block;
        }
        a.trigger:hover { visibility: visible; }

        a.trigger:hover .vml_wrap{ width:7777px; height:7777px; }
        }
    </style>
  </head>
  <body>
    <p>hey</p>
    <span class="closer">X</span>
    <a href="#" class="trigger">
        you
        <span class="vml_wrap"><v:rect fillcolor="black" class="vml_bg"><v:fill opacity="0.5" /></v:rect></span>
        <span class="dialog">
            <span class="visible">hi</span>
            <span class="film">
            </span>
        </span>
    </a>
  </body>
</html>
Paul Sweatte
  • 24,148
  • 7
  • 127
  • 265
  • Thanks for the code Paul :) Unfortunately, I don't think it works for me. I should have been more specific, I need to style arbitrary shapes like paths or polygons. Is it possible to extend this technique to them? – Josh Knauer Feb 01 '12 at 16:35
  • 1
    VML uses attributes instead of CSS properties, so the only way to reference them in a style sheet is to add another behavior URL which references a htc which [sets attribute values](http://msdn.microsoft.com/en-us/library/bb263839%28VS.85%29.aspx) – Paul Sweatte Feb 04 '12 at 01:32
  • @PaulSweatte - nice one, you should attach this as an answer. – Eliran Malka Apr 07 '12 at 19:00