Skip Navigation Links » Blog » UpdatePanel-Css-StyleSheet-upon
  • UpdatePanel Css StyleSheet upon partial-refresh bug in IE

    by

    The update panel seems to have a bug when registering an external stylesheet or including css styles from within the contents that will be getting partially rendered. The bug only seems to occur in IE, works nicely in firefox. Impressive indeed.

    My problems started when i had a control that needed to render a link to an external stylesheet, which was quite mm easy and normal. I mean i've been there and done that plenty of times, however this time there were situations in which the stylesheet needed to be registered if my control was included in an updatepanel and kept invisible during inital load, while enabling it only upon a partial postback. TRICKY TRICKY TRICKY!

    More over, there is an old bug opened and closed with a reason "this is by design". Seems awkward to me that this is by design and only effects IE Sad
    The url to the bug report is here :

    https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=103134

    I resolved by registering the css in the OnInit phase of my custom control. Since this would run and register the css even if the control was disabled or invisible, which is what i was after, since it registered the control with the page on first load instead of trying to rendering the style link as part of my rendering for the control(which obviously didn't work in IE).

    A simplied piece of my code of how i have worked around this problem is as follows :

    C#
    
                
    protected override void OnInit(EventArgs e)
    {
        base.OnInit(e);
        ScriptManager sm = ScriptManager.GetCurrent(Page);
        if (!sm.IsInAsyncPostBack)
        {
            string css = string.Format("<link rel=\"stylesheet\" 
    href=\"{0}\" type=\"text/css\" />", 
    ResolveUrl(CssClassFile));
    
            ScriptManager.RegisterClientScriptBlock(this, 
    typeof(MyBlahControl), "MyBlahId", css, false);
        }
    }
    

    Update 01/01/2008 :

    Please read the first two comments below. CSS contianment from within the <body element violates xhtml specs and as such here is an update that includes the css in the <head section. Thanks to Ram Krisna for pointing out/commenting this.

    C#

    protected override void OnInit(EventArgs e)
    {
        base.OnInit(e);
        ScriptManager sm = ScriptManager.GetCurrent(Page);
        if (!sm.IsInAsyncPostBack)
        {
            HtmlLink l = new HtmlLink();
            l.Href = ResolveUrl(CssClassFile);
            l.Attributes.Add("rel", "stylesheet");
            l.Attributes.Add("type", "text/css");
            Page.Header.Controls.Add(l);
        }
    }
    

    A simplified test of what I feel is an open bug and should be fixed can be seen below. After clicking the button, the style applied to the label is lost and happens only in IE7, donno about previous versions since i have not tested :

    ASP.NET
    
                
    <%@ Page Language="C#" %>
    
    <script runat="server">
    
    protected void Button1_Click(object sender, EventArgs e)
    {
        // do something
    }
    </script>
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 
    Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head id="Head1" runat="server">
        <title>Untitled Page</title>
    </head>
    <body>
    <form id="form1" runat="server">
    <div>
    <asp:ScriptManager ID="ScriptManager1" runat="server">
    </asp:ScriptManager>
    <asp:UpdatePanel ID="UpdatePanel1" runat="server">
        <ContentTemplate>
    <!-- 
        Note below that for simplicity i am not
        using an external stylesheet. Anyway, 
        even with an external style
        sheet the result is the same. The style is 
        not applied after partial postback 
        -->
            <style type="text/css">
                .MakeGreen{background-color:green;}
            </style>
            
            <asp:Label ID="Label1" CssClass="MakeGreen" 
            runat="server" Text="Label"></asp:Label>
            
            <asp:Button ID="Button1" runat="server" 
            Text="Partial refresh"
                OnClick="Button1_Click" />
                
        </ContentTemplate>
    </asp:UpdatePanel>
    </div>
    </form>
    </body>
    </html>
    
    



     
    re: UpdatePanel Css StyleSheet upon partial-refresh bug in IE
    by

    I am try to do that but getting an error like script tag not proper outside the script


    re: UpdatePanel Css StyleSheet upon partial-refresh bug in IE
    by
    Gravatar

    hi Rama, I did suspect that initially but then it's quite common to see stylesheet containment done from within the <body element and to make it even worse, this works very well with any major UserAgent i have managed to get my hands on and tested (IE, firefox, Opera, Safari).

    Also while it will be like comparing apple and oranges, i still do see a relation with the javascript containment and how script containment from within the <body is quite common and is the default for pretty much all of the ajax extentions library.

    The browser reads a page from top to bottom fashion so i can't imagine a valid reason why this might be a problem to have css containment done from within the body as long as the content using the css follows.

    I have however done some more research since and while the w3c is vague in their specification as to what the UserAgent should follow, I do not read anywhere on the w3c where they state explicitly that this is not allowed anywhere outside the <head element. An interesting document i found is the following :

    www.w3.org/.../styles.html

    I have gone the extra mile to validate an xhtml document against the w3c validator and surprisingly i got my answer :

    The element named above was found in a context where it is not allowed. This could mean that you have incorrectly nested elements -- such as a "style" element in the "body" section instead of inside "head" -- or two elements that overlap (which is not allowed).

    Seems like a pretty much conclusive and definitive answer.

    So why are all browsers forgiving when css containment is done from within the <body ? I feel this shouldn't be working in the first place, but it does.

    Oh well, to cut a long rant short, I have changed my position on this being a bug in IE (since IE only fails to forgive css containment from within the body, if it's done through script, however something that shouldn't be working or supported anyway as per the specs).

    Leaves a lot of room for confusion since while the validator verifies  that a violation of the specifications has occurred, it's a violation that most UserAgents ignore, inlcuding IE, except in the scenario i presented here in this post.

    I also need to fix my workaround since while presenting a solution, by including the css outside the updatepanel content area, it still violates the xhtml specs, in that css containment is done from within the <body. Please read the update i have added in the post itself above.

    Thanks for response and a happy new year.


    re: UpdatePanel Css StyleSheet upon partial-refresh bug in IE
    by

    Hi Tutto!

    This is more of a browser limitation and is correct. As per XHTML spec you cannot have style element within body.

    style element should always be present in the head section.

    So you markup is ignore by the browser when the update panel updates i.e. innerHTML ignores the <style> markup.


    A penny for your thoughts