Event 1040 - Cascading Style Sheet (CSS Fixes)

Applies To: Windows 7, Windows Vista

Windows® Internet Explorer® 8 and Windows Internet Explorer 7 contain a number of improvements to cascading style sheet (CSS) parsing and rendering over previous versions of Internet Explorer. The goal of the improvements was to increase the consistency of how Internet Explorer interprets cascading style sheets as recommended by the World Wide Web Consortium (W3C), so that developers can have a reliable set of functionality.

In some cases, these changes might make existing content behave in ways that are not compatible with earlier versions of Internet Explorer. You might see this when elements are moved to a different area of the page or in overlapping content when viewed in Internet Explorer 8 or Internet Explorer 7. These issues are common to content using particular CSS constructs (often known as filters) to work around bugs that existed under the strict mode in earlier versions of Internet Explorer.

When Is This Event Logged?

This event is logged when an issue from one of the following four categories is encountered:

  • User Agent Strings and Browser Detection

  • XML Prolog and the Strict Switch Method

  • Box Model Changes

  • CSS Filters

For more information, examples, and additional resources, see the Event 1040-Cascading Style Sheet (CSS Fixes) topic from Internet Explorer Application Compatibility.

Addressing Broken Web Pages

If a Web page is rendering differently in Internet Explorer 7 or Internet Explorer 8 than in previous versions of Internet Explorer, you must diagnose the cause of the problem. The following sections discuss the most common causes.

User Agent Strings and Browser Detection

One possible cause is User Agent String detection. User Agent String detection occurs due to Web sites serving different content depending on the type and version of the Internet browser and not expecting access from Internet Explorer 7 or Internet Explorer 8.

Note

For more information, refer to the Detecting Internet Explorer More Effectively topic on MSDN.

XML Prolog and the Strict Switch Method

The XML prolog specifies which version of XML to use, typically seen in conjunction with XHTML on Web pages. Microsoft® Internet Explorer 6 introduced a method to switch between quirks mode and strict mode, which required the coding to appear at the top of a Web page. Unfortunately, the XML prolog also required appearing at the top of a Web page, with most Web page authors including it after the strict-type switch. In this situation, Internet Explorer 6 ignored the author's intention and rendered the page in quirks mode rather than strict mode. Internet Explorer resolves this issue by allowing the XML prolog to appear immediately following the strict-mode switch. Due to this change, rendering issues can appear due to the mode expected by the content. To verify if this is the issue for your Web pages rendering incorrectly, open the Web page in a text editor and review the first two lines of code. If you see the XML prolog and a strict <!DOCTYPE>, the Web page author must update the content.

Box Model Changes

Internet Explorer 7 and later versions changed the overflow behavior to align with the Cascading Style Sheet 2.1 box model. The overflow method specifies whether to clip content if it overflows your specified size constraints. The default is not to clip content, enabling it to appear outside of the box.

Previous versions of Internet Explorer did not support this behavior. Instead, content always had to fit within the defined space, which meant that the Internet Explorer window had to auto-grow to support the dimensions of the content. For example, if you created a box with a width and height of 100 pixels, you could enter content up to 100 pixels without issues; however, if you exceeded 100 pixels, the window size automatically grew to encompass this new information.

With this model change, any Web page that previously relied on a window to grow automatically will now be displayed incorrectly since Internet Explorer 7 and Internet Explorer 8 respect your size constraints and render accordingly. To demonstrate this behavior, refer to the following code sample.

<style type="text/css">
div        { width : 100px; height: 100px; border: thin solid black;}

blockquote { width: 125px; height: 100px;
             margin-top: 50px; margin-left: 50px;
             border: thin dashed black}
cite       { display: block;
             text-align: right;
             border: none}
p          { margin: 0;}
</style>

<div>
  <blockquote>
    <p>some text long enough to make it interesting.</p>
    <cite>- anonymous </cite>
  </blockquote>
</div>

As you can see, the later versions of Internet Explorer respect the height and width settings of a box, so the <blockquote> content renders outside of the boundaries of the parent box.

CSS Filters

Even though standards like CSS are available, it is not a guarantee that all browsers will render the information the same way. The standard might have undefined parts, browser vendors might not implement components in the same manner, or the existing implementations might have bugs. Based on these standards issues, the Web developer community has developed CSS filters. CSS filters take advantage of browser bugs or unimplemented features to hide CSS style rules from specific browsers. Therefore, as these known standards issues are fixed, some of your CSS filters will stop functioning.

Both Internet Explorer 7 and Internet Explorer 8 have fixes for many of the underlying parser bugs that prevented the following filters from functioning properly on earlier versions of Internet Explorer.

Note

If your Web page contains any of these filters, you must remove or replace them for your functionality to be unimpaired.

* Filter

Used to show rules that are exclusive to Internet Explorer. Internet Explorer 7 and later versions will ignore these constructs.

/* The following rules used to apply only to Internet Explorer, but are now ignored by versions of Internet Explorer 7 and later. */
* html{ 
}
* html body{
}

Underscore (_) Filter

Used to show properties exclusive to Internet Explorer. Internet Explorer 7 and later versions will treat these constructs as a custom property, which means that it is still in the object model and can be queried through a script, but it does not natively apply its value.

/* The following rule used to apply the min-height property to Internet Explorer. In Internet Explorer 7 and later versions, _height is treated as a custom property, so no height value is applied. */
.myclass {
   min-height: 300px;
   _height: 300px;
   ...
   }

/**/ comment filter

Used to hide properties exclusive to Internet Explorer while using the strict mode <!DOCTYPE> switch. Previously, this filter did not work while in quirks mode. Internet Explorer 7 and later versions will parse and apply this property.

/* The following rule used to hide the height property to Internet Explorer. In Internet Explorer 7 and later versions, the value is applied. */
.myclass {
      height/**/: 300px;
   ...
   }

"html > body" child selector filter

Used to hide declarations exclusive to Internet Explorer. Internet Explorer 7 and later versions will parse and apply the properties included in the declaration.

Note

CSS style rules relying on child selectors are only considered CSS filters when used to detect specific browser types or versions.

/* The following rule used to hide the height property to Internet Explorer. In Internet Explorer 7 and later versions, the value is applied. */
html > body {
      height: 300px;
   ...
   }

"head + body" adjacent selector filter

Used to hide declarations exclusive to Internet Explorer. Internet Explorer 7 and later versions will parse and apply the properties included in the declaration.

Note

CSS style rules relying on adjacent selectors are only considered CSS filters when used to detect specific browser types or versions

/* The following rule used to hide the height property to Internet Explorer. In Internet Explorer 7 and later versions, the value is applied. */
Head + body {
      height: 300px;
   ...
   }

"head:first-child + body" first child and adjacent selector filter

Used to hide declarations exclusive to Internet Explorer. Internet Explorer 7 and later versions will parse and apply the properties included in the declaration.

Note

CSS style rules combining first-child selectors with adjacent selectors are only considered CSS filters when used to detect specific browser types or versions.

/* The following rule used to hide the height property to Internet Explorer. In Internet Explorer 7 and later versions, the value is applied. */
head:first-child + body {
      height: 300px;
   ...
   }

Remediation

This section presents possible strategies for working around the CSS-related compatibility problems.

Issues with the Overflow:Visible Default Behavior

If you have not defined a width or height for your boxes, your layout should behave much like it did in Internet Explorer 6. The only exceptions would be if you have long content that overflows the viewing area.

There are two cases where your layout might break due to the new CSS behavior:

  • If you have defined a width or height for your box, not realizing that your content is larger than your set dimensions. To fix this, identify the proper size for your content and set the correct dimensions for your box.

  • If you have content that requires automatic resizing of your box size. Typically, this occurs if you insert your content dynamically or if you do not specify a font size and the text size changes as part of a user's settings.

    At this time, there is an unsupported declarative solution using the minimum and maximum width/height properties. The overflow behavior change is a precursor to support these properties. Microsoft is currently working on implementing these properties, but until they are available, you can use a script solution similar to the one shown in the following code example.

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Strict//EN">
    <html>
    <body id=body1 onload="calc()">
    <!-- Small div with overflowing content -->
      <div id="div1" style="border: solid red 1px; width: 10px; height:10px"> Some overflow text</div>
    <!-- Providing the dimensions to the box to include the overflow content --> 
      <span id="span1" style="position:absolute;border:blue dotted 1px;display:none"></span>
    </body>
    </html>
    
    <script>
    function Rect(t, r, b, l) {
       this.top = t;
       this.right = r;
       this.bottom = b;
       this.left = l; }
    
    function Size(w, h) {
       this.width = w;
       this.height = h; }
    
    function calc() {
       // pick up the text range of the body text
       var tr = body1.createTextRange();
       // move to the element for which you are identifying the dimensions 
       tr.moveToElementText(div1);
    
       /* Returns the TextRectangle collection.
          Each rectangle has four integer properties (top, left, right, and bottom), which represent a coordinate of the rectangle, in pixels. */
    
       var rects = tr.getClientRects();
       /* we know the top left corner of the div. but we need to identify the overflow area in the bottom right corner */
    
       var textRect = unionRects(rects);
       /* generate a dummy element just to show the new border in addition to the old. You will probably want to override the given dimensions on div1 */
       span1.style.display = "block";
    
       // Get divs location on the page
       var offsetDiv1 = getOffset(div1);
    
       /* Calculate the actual dimensions starting at the upper left corner of the div and going to the size required for the overflow text */
       span1.style.height = textRect.bottom - offsetDiv1.height;
       span1.style.width = textRect.right - offsetDiv1.width;
       span1.style.top = textRect.top + offsetDiv1.height;
       span1.style.left = textRect.left + offsetDiv1.width; }
    
    function unionRects(rects) {
    
       var l = 0;
       var r = 0;
       var t = 0;
       var b = 0;
    
       for (var i = 0; i < rects.length; i++) {
    
          l = Math.min(l, rects[i].left);
          t = Math.min(t, rects[i].top);
          r = Math.max(r, rects[i].right);
          b = Math.max(b, rects[i].bottom); }
    
       return new Rect(t, r, b, l);   }
    
    function getOffset(element) {
    
       var w = document.body.offsetLeft + element.offsetLeft;
       var h = document.body.offsetTop + element.offsetLeft;
    
       for (; element.tagName != "BODY"; element = element.offsetParent)  {
          w += element.clientLeft + element.offsetLeft;
          h += element.clientTop + element.offsetLeft;}
    
       return new Size(w, h);  }
    </script>
    

Issues with the CSS Filter Enhancements

If your Web page layout does not appear correctly while in the Internet Explorer 7 or Internet Explorer 8 strict mode, you have two options:

  1. Attempt to create a standards-based, cross-browser design. By simplifying your Web page, you might remove the problem, in addition to reducing your maintenance cost.

  2. Use conditional comments to work around the issues that affect only Internet Explorer. If you must use CSS filters, consider using filters that only target older browser versions to minimize your risk of future problems.

Using Conditional Comments

Conditional comments provide an easy and maintainable way to detect Internet Explorer's browser type and version. Since the syntax is comment-based, other Internet browsers ignore the statements.

You can use conditional comments to replace the CSS filters that specifically try to target Internet Explorer, such as the * HTML filter. For easier maintenance, you can use conditional comments to create a link to an Internet Explorer-specific style sheet.

<!--[if IE]>
    <link rel="stylesheet" type="text/css" href="iestyles.css" />
<![endif]--> 

Using CSS filters

CSS filters are reasonable options to work around the differences in browser behaviors. However, you should use the filters with two guidelines in mind:

  • Target only earlier versions of an Internet browser. This ensures that your filter will not break with new browser releases. For example, there are filters that target only versions of Internet Explorer 5.5 and earlier, so they are relatively safe to use.

  • Be aware that you must maintain your filters if issues occur, for example, if there is a security update for a previous operating system version. You must also provide comments, clearly marking the code as a CSS filter.

See Also

Concepts

Known Internet Explorer Security Feature Issues