Sponsored By Aspose - File Format APIs for .NET

Aspose are the market leader of .NET APIs for file business formats – natively work with DOCX, XLSX, PPT, PDF, MSG, MPP, images formats and many more!

Silverlight, FireFox and 100%

In my last post I mentioned something nice about FireFox. In this post I’ll talk something not that nice about FireFox and the way we, more or less, worked around it.

A lot of people complain about Silverlight not working in Firefox. Including myself. Our DeepEarth page looks great in IE or Safari but in Firefox there is nothing to be seen at all. Not even an error message. There is quite a discussion on Silverlight and Firefox over here which branches in many directions. Thanks to Willem who spotted the one comment by Makkros which was the key to the solution.

The problem with Silverlight in Firefox has all to do with sizing. Take this snippet of the webpage

<div class="mapStyle">

   <asp:Silverlight ID="TrackingMap" runat="server" Source="~/ClientBin/TrackingMap.xap"  />

</div>

It’s a silverlight control enclosed in a div. As the control displays a map the best thing would be to claim as much space as available

<div class="mapStyle">

   <asp:Silverlight ID="TrackingMap" runat="server" Width="100%" Height="90%" Source="~/ClientBin/TrackingMap.xap" />

</div>

This works in IE and Safari (and maybe more). When the browser window is resized the control takes up all space available with the div wrapping around.

Alas things work different in Firefox. Googling on Firefox DIV 100% results in many many hits. Firefox first sizes the DIV and then it’s up to the content to use it. Resulting in content sized 0 by 0. Which comes pretty close to invisible.

So you have to set the size of the control in absolute measures to see it. And resize it later on from script.

<div class="mapStyle">

   <asp:Silverlight ID="TrackingMap" runat="server" Width="500px" Height="300px" Source="~/ClientBin/TrackingMap.xap" />

</div>

Alas this does not solve things at all. The initial size is OK, but resizing the control will not resize the wrapping DIV. Sizing the control over it’s initial size will crop a part, sizing it under it’s original size will result in an undesired border. It requires a full page refresh to get things into proportion again.

In the end I came up with this solution. Not that elegant, but it works. Any suggestions for something better are more than welcome.

In the page load of the code behind the control is given it’s initial size. A number of pixels for FF, a percentage for the rest.

protected void Page_Load(object sender, EventArgs e)
{

    if (! IsPostBack)
    {      

        if (Request.Browser.Browser.ToLower() == "firefox")
        {
            TrackingMap.Width = new Unit(mapWidth, UnitType.Pixel);
            TrackingMap.Height = new Unit(mapHeight, UnitType.Pixel);
            FireFoxWidth.Text = mapWidth.ToString();
            FireFoxHeight.Text = mapHeight.ToString();
            FireFoxSupport.Visible = true;
        }
        else
        {
            TrackingMap.Width = new Unit(100, UnitType.Percentage);
            TrackingMap.Height = new Unit(88, UnitType.Percentage);
        }
        
    }

}

The number of pixels for the initial size is hard to guess. The browsercapabilties always suggest a 640*480 screen. Not that useful; I have to take arbitrary values. To house it I created two properties which store the values in the session

private const string ffMapWidth = "FFmapWidth";
private int mapWidth
{
    get
    {
        var o = Context.Session[ffMapWidth];
        if (o == null)
            return 1024;
        return int.Parse(o.ToString());
    }
    set
    {
        Context.Session[ffMapWidth] = value;
    }
}

private const string ffMapHeight = "FFmapHeight";
private int mapHeight
{
    get
    {
        var o = Context.Session[ffMapHeight];
        if (o == null)
            return 768;
        return int.Parse(o.ToString());
    }
    set
    {
        Context.Session[ffMapHeight] = value;
    }
}

It’s up to the user to pick a new size for the control, that’s what the FireFoxSupport control is for. That has two textboxes to enter the size and a button to perform the actual resize.

protected void resizeMap(object sender, EventArgs e)
{
    try
    {
        mapWidth = int.Parse(FireFoxWidth.Text);
        mapHeight = int.Parse(FireFoxHeight.Text);
        Response.Redirect(Request.Url.ToString(), true);
    }
    catch
    {
        FireFoxWidth.Text = mapWidth.ToString();
        FireFoxHeight.Text = mapHeight.ToString();
    }
}

The new desired size is read from the textboxes and stored in the session using the properties. A complete rebuild of the page is enforced, the page load will now set the map to the desired size. And the div will wrap right because it’s a brand new page.

I don’t like this very much, but at least it does work. The only other working scenario I could imagine to circumvent the user taking care of the size is forcing a page refresh after a browser resize. Which stinks even more and will still leave the problem of finding out the available room. Which is a matter of chicken and egg.

I don’t want to get involved in any holy war on browsers or w3c but I really do believe Firefox does this completely wrong. Silverlight is not the only content suffering.

This entry was posted in Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://codebetter.com/members/pvanooijen/default.aspx pvanooijen
  • http://www.megawars3.com David Baity

    It appears to be the Form height is the problem.

    This was tested on IE, FF, Opera and Safari they all seem happy



  • JamesEJ

    I’ve checked this out. CSS1 says about percentage widths ‘Percentage values: refer to parent element’s width’. IE etc break this by considering the parent element’s width to be that of the browser when it has no value (whereas it should be the width the browser gives it at display). Firefox breaks this by apparently not calculating percentages from parent to child but the other way round, in which case only fixed-size parents are considered to be non-zero. Both browser implementations are idiotic but IE works with Silverlight. This is why I avoid working with HTML at any opportunity and why I (mostly) love Silverlight and XAML – which incidentally calculates this very basic layout algorithm properly.

  • http://petersgekko.codebetter.com pvanooijen

    Thanks everybody

    These solutions are not as easy/good as thet seem at first sight. I’ll do a larger follow up on in which I will discuss all solutions proposed

  • JohnM
  • http://petersgekko.codebetter.com pvanooijen

    Phillip, no problem.

    I’m sorry it does not work that way. What I want is my map claim the space and I want the div container to follow and just wrap around. IE and Safari do it that way. FF doesn’t.

    A major reason for wanting this kind of behavior, and not the other way round where the container dictates the size, is the possibilty to build small snippets of the page, like an ascx, which need (and have) no knowledge of their container.

  • Phillip

    I didn’t mean to sound harsh or start any browser war, It just annoys me when tool is blamed when it’s not the tool.

    I understand what your trying to do but thats simply not how it works.

    If you had put a defined height/width, the parent container knows the height/width it needs to auto to in order to contain the child.

    When you start using percentages, the parent container doesn’t know what it needs to be, it assumes its already the correct size to fit 100% height/width.

    That is why we need to make the parent the right height/width so the child can be 100% of that parents height/width.

    :)

  • http://petersgekko.codebetter.com pvanooijen

    As said in the post, I don’t want to get involved in any religious wars on browsers or the “correct” way to work with CSS.

    What worries me in Phillips’s story is that the responsabillity is brougth to the container. What I want is a div (in a usercontrol, a page or whatever) which uses all space left over by the rest of the page. No more. No less.

    Phillip does put the finger on the aching spot.:

    “In firefox it considers the div completely empty ”

    Firefox is imho just wrong.

    But i will run through the CSS stuff and keep looking for a solution which is browser independent.

  • Phillip

    He’s blaming the tool. The tool is not the problem.

    Maybe you should go try it yourself. Both IE and Firefox work correctly in regards to 100% height. The div’s are correct, they will not display 100% height if the parent container has no height.

    If you give a div or block element a defined height, the parent container doesn’t matter.

    When you add a percentage height, that percentage is the percentage of the parents visible height.

    In the problem address the body/html/containing div, have no defined height, so the silverlight cannot have a percentage height.

  • Frank Schwieterman

    Phillip, don’t be so rude if you’re also going to be wrong. The only element that needs to have its height set is the containing div. The body and html tags do not need to be sized.

    Here’s a great site that shows CSS/HTML usages that work across browsers: http://www.cssdesignpatterns.com/ Theres a book that goes along with it as well.

  • Phillip

    Firefox cannot set a height of 100% on an element where the parent has no height to begin with.

    Your problem is a lack of understanding HTML/CSS and the Browser.

    Create a new HTML page and put in the CSS:

    < !DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">





    Open it in IE and Firefox, you will notice in IE theres a small green bar, in firefox there isn’t, the reason this happens is IE add’s height due to the font-size and line height of blank text inside the div, even tho the blank text does not exist.

    In firefox it considers the div completely empty so it has no height what so ever.

    Ok now that you have seen that, set the height 100% on both the HTML and Body element, and you will notice the green takes up the entire browser window… in both IE and Firefox.

    This is not a firefox issue.

  • Stephen

    I always think of this as a bit of a hack but doesn’t it work?

    html, body
    {
    height: 100%;
    }

  • http://petersgekko.codebetter.com pvanooijen

    @Matt: Thanks. No problem. Silverlight is not in the LiveWriter dictionary and easy to misspell for a non native.

    @Brian: Tried that, no way..

  • Brian

    I don’t work in the ASP (or Silverlight, for that matter) stack, so I feel a bit (read: WAY) out of place saying anything here, but have you tried messing with the CSS of the wrapper div? Maybe setting the div’s dimensions (or overflow) via CSS would help.

    Good luck, and thank you for considering other browsers/platforms in your project, even though they are giving you headaches :)

  • http://blog.mattcorr.com Matt Corr

    Nice article.
    I don’t mean to be a grammar/spelling Nazi but Silverlight is misspelt a few times, and for some reason it seems to stick out.