Tag Archives: scrollbars

Position ribbon and disable fake scrollbars in SharePoint 2010

The default Sharepoint 2010 ribbonSharePoint 2010 introduced the ribbon, which is a good idea — it puts a lot of admin/navigation/editing controls in a consistent place, with the content changing based on the page and task at hand.

Its approach to positioning the ribbon, however, leaves a lot to be desired.

The basic problem is that SharePoint uses javascript instead of CSS to fix the ribbon to the top of the browser window. One little-known side effect of this approach is that SharePoint turns off the browser’s built-in scrollbars and replaces them with its own javascript versions.

This creates three big drawbacks:

  1. Users can’t scroll until the entire page is loaded;
  2. It makes in-page anchor tags useless;
  3. The scrolling behavior routinely breaks in Google Chrome.

The first two are annoying; the last one is a killer, especially for public-facing sites. So if you’re building a public-facing SharePoint site, here’s how to turn off the SharePoint scrollbars and position the ribbon with CSS. Thanks to Kyle Schaeffer for pointing the way. His blog is an excellent resource for SharePoint-related items.

Warning: Only do this on publishing pages

Avoid using this technique on non-publishing sites or on system master pages. SharePoint uses javascript to calculate the position of a lot of dynamic elements on system pages, and the changes outlined below could seriously affect that math, resulting in weird behavior.

#1: Edit the body tag

In your master page, delete “scroll=no” from the <body> tag. This fixes scrolling in older browsers.

#2: Add javascript

The following javascript overrides the SharePoint function that positions the ribbon and creates the scrollbars. It determines if a ribbon is present and, if so, adds enough padding to the top of #s4-workspace so the page content is visible below the ribbon. Add it to your master page, either inline or through an external script link:

 

function FixRibbonAndWorkspaceDimensions() {
    ULSxSy: ;
    g_frl = true;
    var elmRibbon = GetCachedElement("s4-ribbonrow");
    var elmWorkspace = GetCachedElement("s4-workspace");
    var elmTitleArea = GetCachedElement("s4-titlerow");
    var elmBodyTable = GetCachedElement("s4-bodyContainer");

    if (!elmRibbon || !elmWorkspace || !elmBodyTable) {return;}
    if (!g_setWidthInited) {
        var setWidth = true;
        if (elmWorkspace.className.indexOf("s4-nosetwidth") > -1)
        setWidth = false;
        g_setWidth = setWidth;
        g_setWidthInited = true;
    }
    else {var setWidth = g_setWidth;}
    var baseRibbonHeight = RibbonIsMinimized() ? 44 : 135;
    var ribbonHeight = baseRibbonHeight + g_wpadderHeight;

    if (GetCurrentEltStyle(elmRibbon, "visibility") == "hidden") {ribbonHeight = 0;}
    // Override default resizing behavior
    // -- adds padding to the top of the "s4-workspace" <div> if the ribbon exists and has content
    // -- allows the ribbon to be positioned using CSS instead of JavaScript (more accessible)
    // -- checks to see if the page is inside a "no-ribbon" dialog
    var elmRibbonContainer = GetCachedElement("RibbonContainer");
    if (elmRibbonContainer != null) {
        if (elmRibbonContainer.children.length > 0 && document.getElementsByTagName("html")[0].className.indexOf('ms-dialog-nr') == -1) {
            elmWorkspace.style.paddingTop = ribbonHeight + 'px';
        }
    }
}

#3: Adjust CSS

Add the following code to your master page, either inline or through an external style sheet:

body.v4master {
    overflow: visible;
    height: inherit;
    width: inherit;
 }
 body #s4-workspace {
         overflow: visible !important;
 }
 body #s4-ribbonrow {
         position: fixed;
         z-index: 1000;
         overflow-y:visible;
 }
 #s4-ribbonrow .ms-MenuUIPopupBody, #s4-ribbonrow .ms-popoutMenu, .ms-cui-menu[id ^= "Ribbon."] {
         position: fixed !important;
 }
 .ms-dlgOverlay {
         width: 100% !important;
 }

The CSS positions the ribbon, and also overrides SharePoint’s default overflow settings to avoid duplicate scrollbars.

Warning! Warning!

The ribbon has a z-index of 1000, and ribbon dropdowns have a z-index of 1001. So make sure none of your page content has a z-index higher than 999, unless you want it to be layered above the ribbon.

Extra fix that might be needed

If you’re still experiencing weird ribbon behavior (for instance, the page going up behind the ribbon), try going to Site Actions -> Site Settings -> Look and Feel -> Navigation, scrolling to the bottom and choosing “no” for “Allow users to show/hide ribbon”. That should solve the issue, at a small cost in user control.

Additional fix for non-public sites

If the page “jumps” on page load, and this isn’t a public-facing site (i.e., all users will be logged in and thus see the ribbon), add the following CSS:

#s4-workspace {padding-top:44px;}

The jumping happens because the javascript that adds padding to the top of #s4-workspace runs after the page is fully loaded. So the user initially sees the page without the extra top padding for #s4-workspace; when the javascript runs, it adds the correct padding, pushing the top of the page down. By setting a default padding equal to the height of the ribbon, we ensure that the page initially loads with the correct padding.