SharePoint 2010: Using Modernizr and Polyfills in your sandbox

Tuesday, March 20 2012

This is part 4 of the series.  If  you’re picking up the series at this point and you have difficulty following along, take a moment and review the prior posts.


In the last post, we had just linked Modernizr into the project.  in the process of reviewing our modifications, I noticed an error in our strategy (OK, I admit it, I made a mistake).  Let me explain.  When we install our solution, we are installing it in the root site of our site collection imageso that it available for all sub sites of the root site.  Rather than using the “~site” placeholder in our path, we need to point our path to the site collection root, not the current site.  The reason is simple. Unless we modify the masterpage on a sub site, it uses the template for its parent or the root site.  Additionally, all those “js” and “css” resources also exist only in the root, unless we create a copy of them in our sub site.  Obviously, best practices would dictate that only one copy of the Masterpage and the resources exist.  That way changes are consistently maintained from a single location.  The solution is fairly simple.  We replace those “~site” placeholders with “~sitecollection”.   SharePoint decided to add the “ScriptLink(x)” IDs, so I decided to leave them and an investigation of their purpose for later.


imageThe next step required (there are many good Modernizr tutorials online, just Google “Modernizr Tutorial”) is to add a class to the HTML tag of our masterpage.  What happens when the page loads and the Modernizr.js file runs, is Modernizr replaces that class statement with an list of the HTML5 features indicating whether or not they are supported in the current browser.  imageThis is a client side -  run time action, so whatever browser is being used will be analyzed for compatibility.  The features prefixed with “no-“ are not supported in the current browser.  The features without this prefix are supported.  There are some subtle differences between the reported feature names and the HTML5 standard, and you can easily identify them either with the Modernizr online documentation of one of the many tutorials.  For example, in out image, the “borderradius”  informs us that border radiuses are supported in my browser, however, the CSS attribute for this feature is “border-radius”.  (You may have noticed that I used IE Tools to capture the modifications to the HTML made by Modernizr.  The reason is that IE “view source” only displays the source from the original location, NOT the in memory modified code which is running.)

So what do we need to do to implement those features identified as not supported in our browser?  This is exactly where “polyfills”  come into action.  There is an excellent list of polyfills for HTML5 compiled for us -- HTML Cross Browser Polyfills.  The next step is to decide which unsupported features are required and add the polyfill library(ies) required for our application on the browsers we’ve chosen to support.   Then using the list at HTML Cross Browser Polyfills, we can download and integrate the library(ies) required to support those missing features.


The question of which features to support in your application is not an easy one.  Do you have control over which browsers will be supported by your audience?  Whether the application is intended for the internet, intranet or SP2010Compareextranet may significantly impact that answer.  Trying to support all features would result in a lot of additional JavaScript and CSS code and would likely impact the performance of your pages.  Even if you decide to only support Microsoft Internet Explorer, the differences in HTML5 features supported in each version is significant (the IE10 data below is from the current pre-release of IE10 which is part of the Developer Preview).


The next important question is which features are REQUIRED for your page.  Because many of the features “fail gracefully”, careful consideration should be given to whether the added code weight and complexity of the additional features is worth the performance impact.  In my first post of the series, I showed an image of the IE8 verses IE9 rendering of the content with “border-radius”  styling.  If that was the only feature I was interested in supporting in my pages, then I would likely choose to let the IE8 user see the content with square corners and edges.


The following table identifies which HTML5 features are supported in each IE versions 8 through 10.  It should become apparent that as newer versions of Internet Explorer are deployed, many of the new HTML5 and CSS3 features will come natively and much of the complexity of integrating polyfills will become unnecessary and a wasted effort.  As  you will see later after we’ve added more features, Internet Explorer 10 actually outshines the competitors in HTML5 rendering.  I’ll leave it to you to draw you own opinions and conclusions.

  IE8 IE 9 IE 10  
  no-flexboxr no-flexboxr no-flexboxr  
  no-flexbox-legacyr no-flexbox-legacyr flexbox-legacyr  
  no-canvasr canvasr canvasr  
  no-canvastextr canvastextr canvastextr  
  no-webglr no-webglr no-webglr  
  no-touchr no-touchr no-touchr  
  no-geolocationr geolocationr geolocationr  
  postmessager postmessager postmessager  
  no-websqldatabaser no-websqldatabaser no-websqldatabaser  
  no-indexeddbr no-indexeddbr indexeddbr  
  hashchanger hashchanger hashchanger  
  no-historyr no-historyr historyr  
  draganddropr draganddropr draganddropr  
  no-websocketsr no-websocketsr websocketsr  
  no-rgbar rgbar rgbar  
  no-hslar hslar hslar  
  no-multiplebgsr multiplebgsr multiplebgsr  
  no-backgroundsizer backgroundsizer backgroundsizer  
  no-borderimager no-borderimager no-borderimager  
  no-borderradiusr borderradiusr borderradiusr  
  no-boxshadowr boxshadowr boxshadowr  
  no-textshadowr no-textshadowr textshadowr  
  no-opacityr opacityr opacityr  
  no-cssanimationsr no-cssanimationsr cssanimationsr  
  no-csscolumnsr no-csscolumnsr csscolumnsr  
  no-cssgradientsr no-cssgradientsr cssgradientsr  
  no-cssreflectionsr no-cssreflectionsr no-cssreflectionsr  
  no-csstransformsr csstransformsr csstransformsr  
  no-csstransforms3dr no-csstransforms3dr csstransforms3dr  
  no-csstransitionsr no-csstransitionsr csstransitionsr  
  fontfacer fontfacer fontfacer  
  generatedcontentr generatedcontentr generatedcontentr  
  no-videor videor videor  
  no-audior audior audior  
  localstorager localstorager localstorager  
  sessionstorager sessionstorager sessionstorager  
  no-webworkersr no-webworkersr webworkersr  
  no-applicationcacher no-applicationcacher applicationcacher  
  no-svgr svgr svgr  
  no-inlinesvgr inlinesvgr inlinesvgr  
  no-smilr no-smilr no-smilr  
  no-svgclippaths svgclippaths svgclippaths  
I’ll take you on a very short trip through some dead ends that I encountered during this post.  My interests for this part of the post were mostly CSS3 related features. image I started by looking at the CssPie Library. I later realized that the preferred deployment uses an “htc” file uploaded to the server to manage some of the behaviors required for the polyfill.   Unfortunately, SharePoint Online does not allow the “htc” file type.  So I switched to the CssFx Library which has a very robust list of supported features.  This library required a class attribute on the link tags for the CSS.   CssRegistration in SharePoint did not support a “class” property.   Digging in the initialization method for the CssFx Library I was able to modify the library to work with our masterpage.  We’ll look at those code changes later in the post.   
After integrating that library, I found that some of the prefixes and configurations that were auto-generated, did not give me the expected rendering.  I hand coded some of the vendor specific code to achieve the desired results.  If this doesn’t make much sense to you now, don’t worry, it will be more clear as we look at the steps during the post.  My main point here was to demonstrate that integrating external libraries with SharePoint is a bit of an adventure, but if you work at it, almost anything is possible.
Integrating the CssFx Library was accomplished in exactly the same way we’ve been integrating our other JavaScript libraries.   Getting the JavaScript into the masterpage was the imageeasy part.  The challenge occurred when I needed to add the “cssfx” class to the link tag.  SharePoint uses the CssRegistration component to register the custom css file in our masterpage.  Unfortunately, “class” is not a defined property of that component.  With a little head scratching, I was able to figure out that the reason the class needed to be assigned to the style sheet link, is so that the link reference could be selected from the DOM by the library.  Although not as elegant as I might have liked in my solution, I could use the “href” attribute of the link to select the needed link.  It meant hand coding the initialization method on the library, but this was a masterpage, so the solution was reasonable.  I commented out the code that selected the links based on class and added my selector based on the Uri of the style sheet.
Now back to the styles.  I had decided that what was needed most was a gradient to replace imagethat awful pattern I created for the s4-title banner background.  Cool, that would make the text display more clearly and would improve the overall appearance … except for one small detail.  If you look at the table of features above, you can see that the gradient feature is not supported natively until IE10.  No Problem.  imageThat’s what polyfills do, right?  Well, kind of.  Gradients have been available in IE since 5.0, however, their implementation was very proprietary.  CssFx failed so I found myself searching the net for information on HTML gradient rendering.  I found the perfect resource.  I needed to use Firefox for the online tool --   because IE did not support gradients and it was impossible to configure the settings visually.  After tweaking all the setting and selecting the IE9 Check Box, ColorZilla provided me with the css that needed to be added to my style sheet to handle gradient feature in my browsers, including the proprietary DXImageTransform.Microsoft.gradient settings required by IE.
I won’t do a line-by-line explanation of the css code, but by looking at the code files, you will be able to quickly understand what is happening here. 
The next step was to add a little box-shadow CSS3 effect to add some depth and character to the page.  While I was at it, I’d try applying our border-radiusimage to the content areas and drop shadows.  This time I went right to a CSS3 generator online to Generate the CSS for the various browsers.  There is a great resource online for these CSS generators.  Bookmark this site and use it when generating cross browser CSS -- 1stWebDesigner Web Design Blog.    I used the CSS3 Generator.  After a little tweaking and adjusting I finally was satisfied with the effect.  Please refer to the css code at the CodePlex site if you want a closer look at the style changes. 
So now that we have the “look” we want on our masterpage, let’s take a look at it in the current browser versions and the Developer Preview version of IE10.  My feeling was that IE 9 & 10 were the most accurate at rendering as expected.  Both Chrome and Firefox failed to round the top borders of the ribbon bar.  Worse, Chrome had it’s own unique idea about how to render the picture in the rounded frame created by the border-radius style.  Take a look at the screen shots with these links and see what you think.image
Google Chrome
Mozilla Firefox
Internet Explorer 8
Internet Explorer 9
Internet Explorer 10
As done previously, this solution was uploaded to my SharePoint Online site, and worked as expected.  I will be updating the CodePlex project and will hopefully have it updated by the time you are reading this.
For our next post, we’ll take our new masterpage, and, using the JavaScript Client Object Model, attempt to do a little “mashup” of data both from our SharePoint site and from an external source.  By then we should have a great masterpage template.  I’m looking forward to more feedback and contributions  from the community.   Until then, download the new code and start creating your own CSS3 and HTML5 effects.
Thanks for visiting.