Inherit Expression for IE?

Published 10 years, 10 months ago

The reset styles are currently held up on a point of non-support in IE/Win.  However, there’s a decent chance we can work around it.  I’m hoping you (or someone you know) can help.

One of the things I indicated was problematic, but that I would keep, was the use of inherit for a few properties.  This value isn’t supported by IE/Win, and while I’m okay with including it anyway, it could cause confusion for others trying to use my reset styles.

Priit Pirita suggested the use of IE expressions to simulate inheritance.  For example:

 font-style: expression(
   this.parentNode.currentStyle ? 
   this.parentNode.currentStyle.fontStyle : 
   ‘normal’);

That would assign the weight of the parent element for any element whose parent had a currentStyle, and fall back to normal in any case where that wasn’t true.

Cool enough, assuming you’re okay with using expressions, but there are a couple of wrinkles I haven’t quite worked out.  The first is this:

 font-family: expression(
   this.parentNode.currentStyle ? 
   this.parentNode.currentStyle.fontFamily :
   ‘[...???...]’);

What should be filled in for the [...???...]?  The font family that IE/Win uses by default when first installed?  A null value?  Something else?  I dunno.  Hopefully someone here does.

The second problem is that some people have reported errors generated by expressions; see this comment by thacker for an example.  Can anyone explain why those errors happen and how to avoid them?

The end goal here is not only to come up with inherit equivalents for font-weight, font-style, and font-family, but also to come up with a generic method of simulating inherit for any property.  Doing so would be an enormous boon to developers, so here’s hoping we can pull together and solve this puzzle.  Thanks!

  • Published
  • Categorized under CSS
  • 28 responses so far

  1. There can be no errors…. (MSDN: The topmost object returns null as its parent) Topmost object is btw HTML’s parent and it indeed returns null.

    Eric, I would appreciate if you find time to comment my suggestion of using ‘monospace’ in font-family.

  2. Sorry, Priit, but as noted, errors were reported by thacker, so apparently there can be errors.

    I can’t comment on your use of ‘monospace’ until I’ve learned a good deal more about how the expressions work. What sort of comment were you hoping to see?

  3. 1. Yeah :-)

    2. I was hoping a comment concerning the “special case” of font-family, which is not “hard”, but “blurry” default value and that one can not set such blurry defaults to something hard and usable. That’s why I suggested monospace as an alerting typeface, to signal, that font-family is not set.

  4. I wonder why one would need to check for this.parentNode.currentStyle. All elements should have the currentStyle property. To me the only useful check seems to be that for this.parentNode, but then again, it would be more sensible to just not use that expression for the html element.

  5. You could use document.body.documentElement.currentStyle.fontFamily as the default. The node is guaranteed to exist and should therefore have a computed fontFamily.

  6. Ermm, make that document.documentElement, not document.body.documentElement.

  7. […] Expression for IE? Eric Meyer is looking for IE? expression-savvy webdevelopers to find a solution for IE’s lack of support for the inherit property. Go help him […]

  8. Dao,
    you should check this, because during page loading things are different and html does have parentNode too.

  9. The reported error exists within Internet Explorer whenever the Pirita CSS JavaScript is referenced via a conditional commented style sheet regardless of DTD or MIME type specification.

    Reasonable argument can be presented that since this an exclusive IE workaround and that conditional commented style sheets are ignored by the W3C CSS validation engine, that placement of such a workaround should, in theory, be placed within a conditional commented style sheet.

    However, in practice, this will produce errors in IE.

    Why, I have no idea. If a workaround exists for the workaround, I have no idea. ::chuckling::

    I am simply reporting what I am finding — like it or not.

    Sidebar: My gut reaction is that within the year, the IE inherit issue may become moot. My guess is that IE.NEXT will be released sooner than later. That is purely opinion based upon “not much of anything of substance”. Take it for what it is.

    The monospace font issue: Sounds reasonable as an alert to the developer/designer that a font-family has not been specified for a particular element. For that matter, use the “BiG BaDD KiLLa GaNGsTa DadDy FoNT” for the default providing the designer has that baby installed.

    Thank you very much.

  10. thacker,
    indeed there is error, but very strange one, not a javascript error. I cannot reproduce it anymore, sounds funny, but true. It dissapeared and does not occure anymore, but it was there :-) Sounds like a snake oil, but try to use double quotes and let me know.

  11. Priit; Eric–

    The single quotes were causing the issue and changing them, as suggested by Priit, to double quotes resolves the error.

    This segment of a reset can be broken out, if desired, and used explicitly within a conditional commented style sheet without producing errors [which were possibly parsing errors] in IE and will also be ignored by the W3C CSS validation engine.

    {font-style:expression(this.parentNode.currentStyle ? this.parentNode.currentStyle.fontStyle:"normal");
    font-weight:expression(this.parentNode.currentStyle ? this.parentNode.currentStyle.fontWeight:"normal");
    font-family:expression(this.parentNode.currentStyle ? this.parentNode.currentStyle.fontFamily:"monospace")}

    Thank you.

  12. You can call a javascript function from the css expression like the following to help make the code more readable and more generic.

    <script type="text/javascript">
    function inherit(o, prop, value)
    {
    return o.parentNode.currentStyle ?
    o.parentNode.currentStyle[prop] : value;
    }
    </script>

    <style type="text/css">
    div {color:red;}
    a {color: expression(inherit(this,'color','#000'));}
    </style>

  13. Which version of IE is thacker having the issue in? My initial try in IE caused issues, but this is because I forgot to convert the special ‘ char that quotes are converted to in the posting. Once I changed the “special” quotes to normal quotes it worked fine in IE 5.01, 5.5, & 6 on winXP.

    One thing to note about the expression() value is that it executes JavaScript. When JavaScript is turned off the expression() is never calculated. However, because it is JavaScript, the default could be a variable. Unfortunately if the variable doesn’t exist (unless it is an object property) it will cause an error. So something like –

    font-family: expression(
    this.parentNode.currentStyle ?
    this.parentNode.currentStyle.fontFamily :
    xFamily );

    wouldn’t be a good idea, but you could do something similar to

    font-family: expression(
    this.parentNode.currentStyle ?
    this.parentNode.currentStyle.fontFamily :
    top.xFamily );

    if top.xFamily doesn’t exist it simply treats it as a null or empty value & displays whatever IE’s default is.

    When using expression() just be aware of some of the things others have discovered – 456 Berea Street – IE expressions ignore CSS media types

  14. Patrick–

    I was having issues with IE 6 and 7 only when the script was referenced via conditional commented style sheets. Changing the single quotes to double quotes, as you did, resolved the IE errors.

  15. Do you have to do anything?

    In the case of font-family, do you need to specify anything? As far as I know, the default value of font-family is inherit (or at least, the functionality is the same).

    Nearly every element uses the same font-family as its parent, unless you explicitly overrule it. The only exceptions are elements like <code>, which have a default monospace font.

    So doing nothing might be the best way of solving the font-family problem. Alternatively, as Sebastian said, use document.documentElement.currentStyle.fontFamily throughout the document.

  16. @ppk – you know that IE does not obey the rules so why bother quoting them. ;-)

    Jonathon is on the right track. To get true inheritance you should walk up the DOM tree like this:

    <style type=”text/css">
    p {font-family: wingdings;}
    p.inherit {font-family: expression(inherit(this,"fontFamily","times"));}
    </style>

    <script type="text/javascript">
    function inherit(element, property, defaultValue) {
      function process(element) {
        if (!element) return defaultValue;
        return element.currentStyle[property] || process(element.parentElement);
      };
      return process(element.parentElement) || defaultValue;
    };
    </script>

  17. I could damn well be missing and/or misunderstanding a few things with the overall purpose of a reset style sheet and its functional implementation.

    I am viewing the reset style sheet as more of a design tool that can be removed, or portions of it, prior to moving the content to the production server. I have been assuming that its use and development has and is directed primarily for projection and screen media. [Have not yet evaluated its impact upon print media or creating a separate massive print reset, nor the same for handheld devices.]

    The use of script dynamic properties within a temporary reset file that serves as a visual aide to the developer/designer to insure that elements have been assigned values for font styling seems to make some sense. Keeping it simple and stupid seems to make some sense. Testing the hell out of any script, using a NASA philosophy, prior to deployment makes even more sense.

    Spending ten bucks to solve a nickel problem doesn’t make sense.

    I am leery as hell about the use of client-side JavaScript for a lot of reasons.

    But then as stated, I could be just confused.

  18. Dean,
    are you absolutely sure? The thing is that IE does not evaluate those expressions only once, instead it evaluates them more or less all the time. Which means the less overhead the better or?

  19. My final two-cents–

    To hell with using JavaScript for CSS. I suggest a separate reset IE style sheet within a conditional comment for all IE browsers.. simple and stupid.

    html,body,div,span,
    applet,object,iframe,
    h1,h2,h3,h4,h5,h6,p,blockquote,pre,
    a,abbr,acronym,address,big,cite,code,
    del,dfn,em,font,img,ins,kbd,q,s,samp,
    small,strike,strong,sub,sup,tt,var,
    fieldset,form,label,legend,
    caption{font-style:normal;font-weight:normal;font-family:monospace}

    Anyone see any pitfalls in my logic, please blast away.

  20. @Priit – am I sure of what? The code I posted works, whether it is practical to use it or not is up to the individual. Personally, I wouldn’t bother with expressions to fix such a minor bug.

  21. Dean,
    Are you sure you want to add such overhead to do such a simple thing? As I said, IE evaluates CSS expressions constantly, you move the cursor over the element and expression is evaluated and again and again. And there is lot of tags in Eric’s reset script. Are you sure that running your solution through profiler versus mine, your is not perhaps ten times slower? Are you sure that all this does not affect on browsers responsivness? I do expect you should know IE ten times better than I do, that’s why I am asking…

  22. you should check this, because during page loading things are different and html does have parentNode too.

    That doesn’t overrule my point: it would be more sensible to just not use that expression for the html element.

    Apart from performance, what’s wrong with:
      * {
        font-style: expression(this.parentNode.currentStyle.fontStyle);
      }
      html {
        font-style: normal;
      }

    ?

    Are you sure that running your solution through profiler versus mine, your is not perhaps ten times slower?

    Using expression is expensive in the first place; I don’t think calling a function adds relevant overhead.

  23. @priit – I would recommend *not* using CSS expressions most of the time. As you point out they can be very slow. There are ways round the fact that they are endlessly evaluated but you really have to know what you are doing. To be clear, I recommend not using expressions, especially for something as trivial as this example.

  24. I think the most logical “default” for font-family would be “serif”. Given that most browsers (on Windows at least) seem to use Times New Roman as their default.

    It should certainly be one of the generic families (serif, sans-serif, cursive, fantasy or monospace). serif and sans-serif seem the obvious choices.

  25. @Dean Edwards – Your way is the best way from a feature point of vue. (except I would change:
    inherit(this,”fontFamily”,”times”));
    by
    inherit(this,”fontFamily”,document.documentElement.currentStyle.fontFamily));

    but It’s very slowwwwwwwwwing the page :(. It’s seems IE is calling js expression on any user action.

  26. Good stuff! I use a cross between Yahoo Grids, the 960 Grid and now this in a sort of hybrid solution for my layouts and it works 98% in each browser.

    I’m wondering however if it isn’t required to use javascript hacking if the idea behind the inherit is to remind a person to style the elements rather than depend on inherit as a default directive;

    I’m trying to talk myself out of using any more hacks to make IE behave. Designers are already stuck using Transparent PNG hacks and other HTC (HTML Component) just to get IE to play nice.

    This is a really good post Eric, thanks for the education and perspective.

    ~ Jared Ritchey

  27. Any script execution at the Style Sheet stack of the browser is a performance issue and more importantly a security threat so the use of IE expressions should not be encouraged. It’s a non-standard approach that does not comply with W3C directives.

    Good news is Microsoft is ending expressions in Internet Explorer as announced on Thursday earlier this week. Indeed a very nice move towards the standard-compliant browser.

  28. Hi,
    the trade is indeed a bit dated, but maybe I can help even more.
    The following code snippet helps:

    .inherit_family {
    font-family: expression(this.parentNode.currentStyle[‘font-family’]);
    }

    .inherit_color {
    color: expression(this.parentNode.currentStyle[‘color’]);
    }

    Greetings Werner

Leave a Comment

Management reserves the right to edit or remove any comment, especially when abusive or irrelevant to the topic at hand. HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <em> <i> <q cite=""> <s> <strong> <pre class=""> <kbd>


Comment Preview

If you're satisfied with what you've written, then go ahead...