Positioning a fixed header below the Sitecore Experience Editor ribbon
This post attempts to explain how to integrate into the Sitecore Experience Editor (Page Editor) to move your website’s position: fixed
header so that it is always underneath the Experience Editor’s ribbon. The theory could also be applied to position: sticky
elements.
Let’s say we have this (beautifully designed) header:
Now if that header is styled with “position: fixed”, it’s going to appear behind the ribbon in the Experience Editor:
This makes the navigation nearly impossible to use without closing the ribbon. When the ribbon is expanded, it’s even worse:
Understanding the ribbon’s layout
In order to fix this, we need to understand how Sitecore tries to push down page content when the ribbon is open.
The Experience Editor ribbon UI is actually presented from within an iframe, presumably to avoid conflicting styles or scripts. The (unfixed) page content ends up being pushed down because of an empty div element, called scCrossPiece
, that is sized in sync with the iframe content. Here’s a crude visualisation:
However, because position: fixed
elements are positioned based on absolute coordinates, they aren’t affected by scCrossPiece
. The solution, therefore, is to detect changes to the scCrossPiece container and update the position of the header.
Client pipelines to the rescue
We could simply include Experience Editor-aware javascript in our application code, but that feels like a code smell. Specifically, it’s a violation of separation of concerns and it exposes the fact that our system is based on Sitecore.
Luckily, there is a “Sitecore approved” way of solving this type of problem and that is via “client pipelines”. Client pipelines work similarly to Sitecore’s server side pipelines but are written in JavaScript. In our case, we want to integrate with the “InitializePageEdit” pipeline as that runs when the Experience Editor UI starts up.
First, let’s create our script that will be run by the pipeline. Since there are no events fired when the ribbon is resized, we’ll use MutationObserver to be informed when the div’s style attribute changes. MutationObserver is supported in the latest browsers and IE11, but there’s at least one polyfill that brings support to IE9 and above.
Next we need to create a new PipelineProcessor
item named PositionFixedNavBar
in Sitecore’s core database under /sitecore/client/Applications/ExperienceEditor/Pipelines/InitializePageEdit
. The ProcessorFile
field should be set to an absolute path to the javascript file (eg. “/assets/js/PositionFixedNavBar.js”).
Now, when we load the experience editor the nav is always positioned below the ribbon and the code involved isn’t present in CD environments!
Bonus round: “Sitecore Extensions” support
Sitecore Extensions is a Chrome extension that injects additional UI elements into the Sitecore client to make certain tasks easier. One of these features is a “hide ribbon” button, which is usually more convenient than “closing” the ribbon as the latter requires a page refresh. Unfortunately, the extension hides the ribbon via a CSS class and our implementation so far isn’t aware of that, so it ends up looking like this:
Let’s can tweak our implementation to take the CSS class into consideration:
Now our header is positioned correctly, even when the ribbon is hidden: