Centering Content Properly

As an ASP.NET Developer, not a designer, it’s pretty easy to write crappy HTML. As I have come to learn, content designers will hate you for that. One that has always fooled me is how to properly center content. Centered content is nice sometimes. It put information right in front of the users face, exactly where they expect it. HTML has come a long way since 2000, and it’s worth looking at some of the right and wrong ways to do it. Your designers will love you for it.

The oldest, and simplest way to center content is to use a <center> tag. Designers hate this. It works differently between IE 6 & 7, and 7 will display it differently depending on the DOCTYPE. In quirks mode, it has an interesting effect. If you center a DIV tag in quirks in IE, the DIV will be centered, but the DIV’s contents will be left aligned. That’s actually the behavior we want, but unfortunately not a good option. It only works that way in IE, and your forced to use quirks. If you use standards mode, the center tag behaves correctly: everything is centered, even the content of the DIV, which is not what we are looking for.

To that extent though, you could use a center tag, and just left align the contents of the DIV. Something like this:

   1:  <html>
   2:      <body>
   3:          <p>Some other content here, maybe a header.</p>
   4:          <center>
   5:              <div style="width: 500px; border: solid 1px black; text-align:left;">I want this DIV centered, but the text still left aligned.</div>
   6:          </center>
   7:          <p>Some other content here, maybe a footer.</p>
   8:      </body>
   9:  </html>


Of course I would put my CSS in an external file, otherwise you’ll really catch hell from a designer. Needless to say, it gives the right effect:



snippet



But this really isn’t the best choice. Depending on what your designers have to work with, for say, a product, they may only have access to the style sheets. A center tag is not very flexible, and cannot be put into an external file like a CSS stylesheet.



So what other options are there? Tables would work, but that’s even worse than the center tag, and has the same problem as the center tag: It’s not CSS. So how do you do this using CSS? The trick is auto margins. It’s a fantastic part of the CSS layout that I find surprisingly, not enough developers know about. The HTML looks like this:



   1:  <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
   2:  <html>
   3:      <body>
   4:          <p>Some other content here, maybe a header.</p>
   5:          <div style="width:500px; margin: 0px auto; border: solid black 1px;">
   6:              test
   7:          </div>
   8:          <p>Some other content here, maybe a footer.</p>
   9:      </body>
  10:  </html>


Note that IE, even the famed standards compliant IE 8, will NOT render this correctly without the correct DOCTYPE. IE will leave it left aligned, but Gecko based browsers (Firefox) will still render it correctly.



So why is this the best solution (IMHO)? It’s completely controlled by CSS, and content designers love that.



What’s essentially happening here is the browser is automatically computing the margins for both the left and right side, giving it the appearance of being in the center.

Enum Friendly

Have you ever seen a huge switch on an enum just to return a string? Enumerations can be tricky to deal with, mostly from the aspect of displaying them back to a user. So I whipped up a little code to make it easier to display enumerations, a little extension method. Consider this enumeration:

public enum StatusEnumeration
{
    Normal,
    NotRunning
}


If I want to display this back to a user in English, I can switch on the value, and return “Not Running” when the value is NotRunning. This can be a tad tedious, so I created an attribute to decorate an enumeration. I call it the RenderAsAttribute:



[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
public sealed class RenderAsAttribute : Attribute
{
    private readonly string _renderAs;

    public RenderAsAttribute(string renderAs)
    {
        _renderAs = renderAs;
    }

    public string RenderAs
    {
        get { return _renderAs; }
    }
}


All you do is put this on the enumeration’s values, like so:



public enum StatusEnumeration
{
    Normal,
    [RenderAs("Not Running")]
    NotRunning
}


Notice I put the “RenderAs” on NotRunning. Now for the cool part, a static extension method to make this attribute useful. It would be used something like this:



string notRunningAsString = StatusEnumeration.NotRunning.Render();


Notice how I just call “Render()” on a the value of the enumeration.



public static class EnumRenderer
{
    public static string Render(this Enum value)
    {
        FieldInfo[] enumerationValues = value.GetType().GetFields(BindingFlags.Static | BindingFlags.Public);
        foreach (var fieldInfo in enumerationValues)
        {
            if (value.CompareTo(fieldInfo.GetValue(null)) == 0)
            {
                var attributes = fieldInfo.GetCustomAttributes(typeof(RenderAsAttribute), false).Cast<RenderAsAttribute>();
                if (attributes.Count() == 1)
                    return attributes.Single().RenderAs;
            }
        }
        return value.ToString();
    }
}


This uses refection to look up the value on the enumeration. It’s a bit slow as far as code performance is concerned, but you can easily add caching to it by Type and value. Or, instead of using hard coded strings, you can use the string as a resource key and look up the string in a satellite assembly.

MVP 2009 and other stuff

Recently for April 1st I was re-awarded as an MVP for 2009, and I’m happy to be able to keep doing what I do for the community.

So where has my blog been lately? Well I’ve been focusing on other things at the moment, but I am still blogging. I recently wrote a blog post for my company’s blog about refactoring, and getting your feet wet with it. We’ll see where the series goes too. You can read my blog post about refactoring here:

http://www.thycotic.com/refactoring-code-a-programmers-challenge