Update: I have a different approach to this problem now at: http://www.greggalipeau.com/2011/01/28/a-better-enhanced-sharepoint-2010-floating-ribbon/. I suggest using my new approach rather than this blog as it is much more elegant.
The most innovative (or at least the most visual) enhancement in SharePoint 2010 is the Ribbon structure. The SharePoint 2010 Ribbon shows up for content editors. And, the ribbon stays at the top of the screen no matter how much you scroll down the page. Thus, if you are editing content at the bottom of the page, the Ribbon will stay pinned to the top of your view as you scroll down. SharePoint implemented this system by actually replacing the browser scroll bars with their own scroll bars through javascript. Sounds really cool, huh. Well, the idea is great, but the implementation causes some issues (especially on public facing websites).
Please Note: This issue is mainly for people that are using SharePoint 2010 as a CMS system for public facing sites. Usually the intent of these systems is to keep the ribbon on for content editors, but off for the general public. I am sure techniques used in this article might help in other situations. But, this is the main situation we are trying to solve.
Issues
- Section 508 of the American with Disabilities Act: If you are building a website for the U.S. government you have to comply with section 508 of the American with Disabilities Act. One of the rules is that a page functions when javascript is turned off. This is usually the most ignored rule in building accessible websites because the validity of the rule might be outdated (but, I’m not going to get into that discussion right now). So, if you want to follow the letter of the law, this technique violates this rule because the page isn’t functional (i.e.: can’t scroll) with javascript turned off.
- IPad use: When we built a public Internet site in SharePoint 2010 we noticed that we couldn’t scroll on an IPad. Since the other SharePoint 2010 sites I’ve built were Intranets, I did not know this was an issue until I built my first public site. To be completely fair: scrolling sometimes worked on the IPad, but it is problematic. If the scrolling didn’t work you can change orientation or resize a little and it will come back. But, to our end users reporting bugs on the site, they think it just doesn’t work.
- Anchor tags: Anchor tagging to sections of the page didn’t work. If you have one page www.mywebsite.com?#bottom that links to another page and the section it is linking too is below the scroll area, you get stuck there. It looks really unprofessional when this happens.
Microsoft has addressed how to disable this ribbon behavior: http://blogs.msdn.com/b/sharepoint/archive/2010/04/06/customizing-ribbon-positioning-in-sharepoint-2010-master-pages.aspx
Microsoft is basically saying, you can turn this on or turn this off. So, for public facing sites, you will probably want to turn this off. However, this means you content editors won’t get the ribbon pinned to the top of the page. This will make editing content in SharePoint very, very hard.
Solution
Turn off the ribbon positioning system that SharePoint provides and build your own one with JQuery. The steps are actually pretty simple:
Assumptions
The following steps assume you already know how to do 2 things:
- Create and edit custom master pages in SharePoint
- Create a reference to the JQuery libraries in your custom master page
Steps
-
Turn off the ribbon positioning system
To turn off the ribbon positioning system you need to edit your custom master page with the following:
- Delete the scroll=”no” from the body tag
- Replace the “id=s4-workspace” with id=”s4-workspace-noscroll”
- Delete the following script tag from the master page:<script>
var _fV4UI = true;
</script>
The following steps are optional and are used to override the behavior of SharePoint hiding the title row when in edit mode. Only follow these steps if you wish to override that behavior. It is recommended to override that behavior for this fix as it looks better for the end user.
- Find the class s4-ribbonrowhidetitle (in the s4-ribbonrow tag) and remove the class reference
- Find the class s4-titlerowhidetitle (in the s4-titlerow tag) and remove the class reference
- Find the tag s4-titlerow and change the id to s4-titlerow-nohide
-
Setup the html for JQuery Ribbons
- Add the following right above the s4-ribbonrow:
<div id="scrollingDiv">
- Add this above the s4-workspace tag (or the s4-workspace-noscroll if you made that change):
</div>
- Add the following right above the s4-ribbonrow:
-
Edit the CSS
#scrollingDiv { position: absolute; top:0; z-index:1000; width: 100%; } body {overflow: visible !important } body.v4master { overflow: visible !important }
-
Create the JQuery
$(document).ready(function() { //Replace SharePoint ribbon scrolling with Jquery ribbon scrolling var $scrollingDiv = $("#scrollingDiv"); $(window).scroll(function(){ $scrollingDiv .stop() .animate({"marginTop": ($(window).scrollTop()) + "px"}, "fast"); }); });
-
Fix the ribbon dropdowns
Now that the Ribbon can float/scroll with the page, the dropdown boxes in the ribbon don’t work. The reason is, these boxes use a fixed “top” css property that assumes the ribbon is at the top of the page. We need to change that property to use the top of the scroll position instead of the page.
function setTopPos() { $('.ms-cui-menu').each(function(){ var origTop = $(this).data('origTop') || $(this).position().top; $(this).data('origTop',origTop ); newTop = $(window).scrollTop() + origTop; $(this).css({ top : newTop }); }); } setInterval(setTopPos, 300);
The above code is the best way I could figure out how to deal with the issue. I actually found the idea in this blogged and tweaked it for our purposes: http://www.webpoint0.com/blog/fixed-width-layouts-scrollbar-ribbon-sharepoint-2010/. Using intervals is obviously not the best way to do anything. But, our code never hits the server, so the interval isn’t a horrible thing. I would have liked to catch the event of the dropdown in the ribbon instead of the interval, but I couldn’t figure out the events SharePoint was using to set the dropdown javascript in motion. So, if anyone has a better way to do this, please let me know. It will work now, I just think it can be more elegant. -
Fix the Web Part Edit Panel
Now that the Ribbon floats it covers up the webpart edit panel (this is the panel that shows on the right when you edit the properties of a webpart)
- Add the following CSS to your site
.ms-ToolPaneOuter { margin-top:80px;} .ms-ToolPaneBody{overflow-y:scroll !important;overflow-x:hidden !important}
- Add the following to your custom javascript file
$(document).ready(function() { $(".ms-ToolPaneBody").css({ height: ($(window).height() - 245) + "px"}); var $webPartToolPane = $(".ms-ToolPaneOuter"); $(window).scroll(function(){ $webPartToolPane .stop() .animate({"marginTop": ($(window).scrollTop() + 80) + "px"}, "fast"); }); });
- Add the following CSS to your site
Please Note: In the code above (both the css and the js), there is a static number (80). This number is the amount of top margin for the web part edit panel needed to make sure it is in the appropriate place on the page. That number is optimized for the v4 master page. However, if you create a custom master page (which is what you are most likely doing if you are following this walkthrough). Then you might need to tweak that number depending on the amount of margin and height at the top of your page.
That’s it! Now you have JQuery animation taking care of keeping the Ribbon on top. Why is this better you ask? Well, both my solution and SharePoint’s solution use javascript to implement the ribbon. The difference is, SharePoint’s solution uses javascript to create the scroll area. This means javascript is responsible for whether the site functions or not. My solution uses javascript to position the ribbon. Even if javascript is turned off, my solution will work, the ribbon will just not scroll down with the page. This is OK, because functionally the page will still work, it just will be a little harder to edit content (in that rare case a content editor doesn’t have javascript turned on). In addition, my page will work for the public view on all browser types (including IPads).
The last thing to note about this solution is that your ribbon “floats” on the screen. This means it can cutt off the very top of the page when the page initially loads up. We got around this by running some css for logged in users only (i.e.: only for the people that see the ribbon). In that css, which only runs for logged in users, we just put a top margin on the s4-workspace-noscroll div that is as big as the ribbon itselft. This workaround worked perfectly.
Update: I have a different approach to this problem now at: http://www.greggalipeau.com/2011/01/28/a-better-enhanced-sharepoint-2010-floating-ribbon/. I suggest using my new approach rather than this blog as it is much more elegant.