Home > .net 3.5, AJAX, c#, LINQ, Standards, Visual Studio 2008 > WebGallery 2.0 #5 – CSS Friendly and W3C Compliant

WebGallery 2.0 #5 – CSS Friendly and W3C Compliant

March 3, 2008

In the fifth, and final, segment on the WebGallery 2.0 project, I wanted to touch on the CSS Friendly Adapters and work that went into creating a fully W3C compliant project.

In previous posts, we’ve discussed:

#1 – Introduction
#2 – HttpHandler and LINQ Data Model
#3 – Building the Galleries
#4 – Adding Admin Tools

NOTE: Code downloads are available on the Introduction post.

Having a compliant web site not only increases the potential user pool, but should be a given for any public project.  Gone are the days of web sites that only work in one browser or another.  I know I’m constantly frustrated by Microsoft Exchange’s Outlook Web Access (OWA)—it only renders it’s AJAX view in Internet Explorer, even though the other browsers could probably do just fine.

In addition to compliance, cutting out “junk” code trims down pages and speeds up download times.

CSS Friendly Adapters

The CSS Friendly Adapters, originally a project from Microsoft, is an open project on CodePlex that rerenders common controls like Menu, Login, and GridView into fully CSS-compliant HTML.  What does this gain?  Smaller, cleaner, better looking code that works for everyone.

The great thing about the adapters—you don’t do anything, simply add the libraries and App_Browsers files to your project and they do the rest!

NOTE: Almost everyone.  I’ve been trying to work out a bug with IE6 that I can reproduce in all implementations of the Menu control.  It’s not “breaking”—the borders just show up funky.  I’ve posted up a discussion on CodePlex.

Menu from WebGallery

To create this menu:

<asp:Menu ID=”MainMenu” runat=”server”
  Orientation=”Horizontal”
  CssSelectorClass=”MainMenu” />

The MenuItems are build in code-behind based on the permissions of the user and available galleries, for example:

foreach (var gallery in galleryList)

{

galleryMenu.ChildItems.Add(

             new MenuItem

             {

             NavigateUrl =

“~/Galleries/Show.aspx?id=” +

gallery.Name,

             Text = gallery.Name

             });

}

Using standard ASP.NET styling (Menu Tasks > Auto Format), the unauthenticated (anonymous) menu generates a staggering 115 lines of HTML code.

The auto-generated CSS looks similar to:

<style type=”text/css”>
 .ctl00_MainMenu_0 { background-color:white;visibility:hidden;display:none;position:absolute;left:0px;top:0px; }
 .ctl00_MainMenu_1 { color:White;font-size:0.9em;text-decoration:none; }
 .ctl00_MainMenu_2 { color:White;background-color:#0066CC;font-size:0.9em; }
 .ctl00_MainMenu_3 {  }
 .ctl00_MainMenu_4 { padding:2px 10px 2px 10px; }
 .ctl00_MainMenu_5 {  }
 .ctl00_MainMenu_6 { padding:5px 5px 5px 5px; }
 .ctl00_MainMenu_7 { background-color:#0066CC;border-color:#284E98;border-width:5px;border-style:solid; }
 .ctl00_MainMenu_8 {  }
 .ctl00_MainMenu_9 { background-color:#507CD1; }
 .ctl00_MainMenu_10 {  }
 .ctl00_MainMenu_11 { background-color:#507CD1; }
 .ctl00_MainMenu_12 { color:White; }
 .ctl00_MainMenu_13 { color:White;background-color:#284E98; }
 .ctl00_MainMenu_14 { color:White; }
 .ctl00_MainMenu_15 { color:White;background-color:#284E98; }
</style>

Each menu item looks even worse, the simple “Home” button is shown below.  For a true line count of code, multiple the code below by seven.  Wow.😦

<td>
<div style=”text-align: left; float: left; position: relative;”>
               <a href=”#ctl00_MainMenu_SkipLink”>
<img alt=”Skip Navigation Links” src=”/WebResource.axd?d=T9Y-iBd-ZpV0qN4eBqpPHw2&amp;t=633374031469687500″
width=”0″ height=”0″ style=”border-width:0px;” /></a>

<table id=”ctl00_MainMenu”
class=”ctl00_MainMenu_2″
cellpadding=”0″ cellspacing=”0″ border=”0″>
 <tr>
 <td onmouseover=”Menu_HoverStatic(this)”
onmouseout=”Menu_Unhover(this)”
 onkeyup=”Menu_Key(this)”
id=”ctl00_MainMenun0″>
<table class=”ctl00_MainMenu_4″
 cellpadding=”0″ cellspacing=”0″ border=”0″ width=”100%”>
 <tr>
  <td style=”white-space:nowrap;”>
<a class=”ctl00_MainMenu_1 ctl00_MainMenu_3″ href=”./”>Home</a>
</td>
</tr>
</table>
</td>
. . .
</td>

Once the adapters are added and intercepting those controls, the results are a LOT better, in just about the same amount of space, here’s the ENTIRE menu heirarchy—not just a single item!

<div class=”MainMenu” id=”ctl00_MainMenu”>
 <div class=”AspNet-Menu-Horizontal”>
   <ul class=”AspNet-Menu”>
    <li class=”AspNet-Menu-Leaf”>
     <a href=”./” class=”AspNet-Menu-Link”>
      Home</a>
    </li>
    <li class=”AspNet-Menu-WithChildren”>
     <a href=”Galleries/Default.aspx” class=”AspNet-Menu-Link”>
      Galleries</a>
     <ul>
      <li class=”AspNet-Menu-Leaf”>
       <a href=”Galleries/Show.aspx?id=Default” class=”AspNet-Menu-Link”>
        Default</a>
      </li>
      <li class=”AspNet-Menu-Leaf”>
       <a href=”Galleries/Show.aspx?id=Blog Images” class=”AspNet-Menu-Link”>
        Blog Images</a>
      </li>
      <li class=”AspNet-Menu-Leaf”>
       <a href=”Galleries/Show.aspx?id=Tutorial PDFs” class=”AspNet-Menu-Link”>
        Tutorial PDFs</a>
      </li>
      <li class=”AspNet-Menu-Leaf”>
       <a href=”Galleries/Show.aspx?id=Signatures” class=”AspNet-Menu-Link”>
        Signatures</a>
      </li>
      <li class=”AspNet-Menu-Leaf”>
       <a href=”Galleries/Show.aspx?id=EQ2″ class=”AspNet-Menu-Link”>
        EQ2</a>
      </li>
      <li class=”AspNet-Menu-Leaf”>
       <a href=”Galleries/Show.aspx?id=FFXI” class=”AspNet-Menu-Link”>
        FFXI</a>
      </li>
     </ul>
    </li>
   </ul>
</div>
</div>

Rather than relying on tables, the CSS friendly adapters convert the menu into an unordered list and apply styles accordingly.  In our project, we then customize the styles based on our preferences.

.MainMenu ul.AspNet-Menu /* Tier 1 */

{

    font-size: 0.8em;

    width: 36em;

}

 

.MainMenu ul.AspNet-Menu ul /* Tier 2 */

{

    top: 100%;

    width: 10em;

    left: 0.5em;

    border: solid 5px #284e98;

    z-index: 300;

}

The original CSS Adapter 1.0 page (from Microsoft) has an EXCELLENT white paper explaining the classes used and heirarchy for each generated control.

NOTE: I did find an issue with the Menu control in general (both with the CSS Friendly and standard version)—the arrows (>) didn’t display on Safari or Firefox.  There’s a bit of code, however, that can be added to each page’s base class to work around the issue.

if (

Page.Request.ServerVariables[“http_user_agent”].Contains(“Safari”) ||

Page.Request.ServerVariables[“http_user_agent”].Contains(“FireFox”))

{

Page.ClientTarget = “uplevel”;

}

An uplevel browser is one that supports “advanced” functionality like JavaScript, the DOM, CSS, etc.  According to specifications, this is IE 4.0+ and “all others” fall into “downlevel”. To work around this, and FORCE the application to treat Safari and FireFox as “uplevel” browsers, this bit of code helps. 

What’s odd is I didn’t have any trouble with Opera’s rendering. 

W3C Compliant

The CSS Friendly Adapters go a long way in making the project fully W3C complaint. 

The new ASP.NET 3.5 controls, such as the ListView bridge the rest of the way.  As I discussed in “Building the Galleries,” each gallery is built with a ListView control that generates clean, simple HTML code.  .NET controls are almost non-existant throughout the project which keeps the ViewState short and page sizes small.

Since we, the developers, have full control of what’s rendered on the ListViews, we’re no longer bound by the .NET controls, tables, and odd special tags (remember trying to pass compliance tests with FrontPage?).

Conclusion

There are a few remaining task items to clean up:

  1. Test utf-8 vs. us-ascii as far as file sizes and such across the wire.
  2. Fix the transparency of the Modal Popups—currently it’s using an IE filter for the opacity, there’s got to be a cleaner, more compliant way.
  3. Fix IE6’s menu borders–-all hope cannot be lost!
  4. Add additional data paging options for non-JavaScript web browsers.

Overall, this has been a fun project.  I’ve had an opportunity to dink with LINQ, the new ListView controls, CSS friendly adapters, and create an infrastructure that should (from prelimary tests) move into the MVC framework quite nicely (which is my next goal for the project).  I’ll continue to post code updates and may even move it from my own SVN store up to Google code or CodePlex.

  1. March 3, 2008 at 12:38 pm

    I must be living under a rock. For the longest time my team has been overriding Web Control outputs manually and here is the answer staring right in our face!

  2. March 3, 2008 at 12:51 pm

    @Dennison Uy-

    Assuming you’re talking about the CSS Friendly’s? If so, then yeah, so was I.

    The cool thing is that it’s open! If there’s something you want to do better, change it! A control that’s not included? Add it!

    We (developers) have full control because to operate the package, we compile it–so it’s easy to add little bits and custom pieces here and there. Also, if something good comes up, you can post it back as change/add recommendation for package inclusion.

    The only thing that kinda bugs me, as far as page bytes across the wire, are the CSS names: AspNet-Menu-{whatever}. I get the Menu-{whatever}… but it’s all AspNet and having a few hundred of those, like in a grid/listview adds weight to the page.

  3. Mark Pawelek
    May 21, 2008 at 7:54 am

    It specifically says that CSS Friendly Adapters work with ASP.NET 2.0. I think people will have some difficulty getting them to work with ASP.NET 3.5. I have (difficulty).

    It’s a shame Microsoft didn’t take this opportunity to incorporate the CSS Friendly approach into their controls, perhaps by offering a CSS Friendly property to set for each control.

    The silly names they’ve given to the classes, etc. irritate me too. When I saw the HTML produced by the CSS-friendly menu I gave up on it immediately and wrote my own menu using a control containing a repeater.

    I found this blog while looking for information on how to use Css-friendly controls with ASP.NET 3.5. I’m still looking.

  4. May 21, 2008 at 8:34 am

    @Mark Pawelek-

    So far, so good with getting things to work in 3.5–it’s worked like a dream. I’ve used it for the WebGallery project as well as several enterprise solutions in my job; the code rendered has worked great, is fully compliant, and looks brilliant.

    I’d be interested to know what your issues were incorporating the CssFriendly adapters with .NET 3.5.

    As far as silly names and such, that’s why we’re programmers and we have the source code.

    http://www.codeplex.com/cssfriendly/SourceControl/ListDownloadableCommits.aspx

    To not reinvent the entire wheel, you can easily modify the source code to configure the class names to whatever you want.

    In addition, the Adapters are always in flux–the latest full commit was May 6, but if you find something you want to add, download the code, make the change, and resubmit it as a patch. Here’s a comment from one contributor from April 14th (and that’s being evaluated):

    I am uploading the entire project targeting .NET 3.5. I am using this bits in a production project without problems. Please, consider migrating to .NET 3.5.

    So full 3.5 support is coming.

    As far as Microsoft incorporating it into their basic controls, I totally agree with you there; however, they’re getting better. The new ListView control is a dream come true and other controls are slowly getting better and better.

  1. March 20, 2008 at 12:33 pm
Comments are closed.
%d bloggers like this: