Design Tips for SharePoint 2013 Apps on Tablets and Subnotebooks

If you’ve ever thought about doing a startup you are probably familiar with the idea of the minimal viable product. For Instant Legal Practice and Instant Consulting Practice we decided that this meant focusing on a great experience within Office 365 and Microsoft Office and on some sophisticated backend designs that make it possible for us to be nimble and continuously improve the products. What we want to know is if there is a viable business in Office 365 apps and if our ability to continuously update the products will give us a strong competitive advantage.

Knowing our goals we decided early on that we were not going to invest heavily in different form factors beyond the desktop but that it would be good if we could make the products usable on tablets. Both products are tested and work on IPad 2 (and later), Nexus 7, Galaxy Tab, and Windows Surface. On the IPad they work in Safari. On the Android tablets they work in Firefox and Dolphin, but surprisingly not Chrome for Android which is a shockingly bad browser.

Tip 1: Responsive Design

If you are working on a publishing site or you intend to make big changes to the look and feel, a responsive design is your best bet. Here are a couple of links to get you started: Pro SharePoint 2013 Branding and Responsive Web Development and http://responsivesharepoint.codeplex.com/.

This was not a viable option for us because we don’t use a custom master page as a principle for compatibility with other apps and because our apps depend on list views and the ribbon for much of the user interface. It is probably something that could be made to work for us, but I think it would be a major effort and it is pretty far down the roadmap.

Tip 2: Keep required width to a minimum

This one is pretty obvious. On these devices the base resolutions vary in landscape mode, but most are 980 pixels wide. There are meta tags, CSS, and JavaScript techniques that allow some control over the viewport and zoom behaviors, but as I said we want to keep our initial investment to a minimum and so we focused on making sure the columns in our tabular layouts look good in no matter the width of the browser.

Tip 3: Use CSS effectively

The detail pages for different entities like clients and matters consist of a table at the top and often a set of tabs at the bottom that show related data.

The number of columns in the header varies by entity and also based on the data. In the case of the Clients view the Phone Numbers, Address, and Notes columns are hidden if there is no data.

The tables present challenges because the browser width varies and the width required to display specific data inside the tables also varies. However, using the base of 980 pixels wide gives us a lower bound and we set the min-width of the main content area to 900px and the width of the table to 97%. Finally, in the subordinate elements the vertical alignment is top, there is explicit padding, and the word-break is normal. All, in all, pretty basic stuff.

Tip 4: Leverage the ‘Focus on Content’ Button

The Focus on Content button is located in the upper-right hand corner of the page.

By default, when you click it, it hides all of the chrome including the menus and focuses on the content.

Not focused on content

Focused on content

This could be a great feature, but it was apparently designed by the same folks who figured app webs don’t need menus! It would be better if you didn’t have to continuously touch the button to navigate between pages.

The other day I wrote about Custom Navigation in App Webs. In that post I showed how we use JavaScript to supply menus in the apps. The same script has a monkey-patch to intercept the Focus on Content button and ensure that the primary navigation remains visible.

This is the normal view on an IPad2:

Not focused on content

It is usable if you scroll, but it works much better if you focus on content:

Focused on content

The script is fairly simple.
var oSetFullScreenMode; //Stores the original function in the SharePoint libraries

//If the function exists assign it to the variable for the original function
if (typeof (SetFullScreenMode) !== 'undefined') {
   oSetFullScreenMode = SetFullScreenMode;
}

//Replace the function with a new function
SetFullScreenMode = function (fEnableFullScreenMode) {
   //If the user is enabling full screen mode

   if (fEnableFullScreenMode) {
      //Add some margin to the top of the content area
      $('#contentBox').attr('style', 'margin-top: 20px;');

      //And put the menu into the content area as its first element
      $('#contentRow').prepend(nav);
   }
   else {
      //Otherwise remove the margin and the menu
      $('#contentBox').attr('style', 'margin-left: 220px;');
      $('#contentRow').find('#DeltaTopNavigation').remove();
   }
   //And then run the original function so SharePoint can take care of the rest
   if (oSetFullScreenMode !== undefined) {
      oSetFullScreenMode(fEnableFullScreenMode);
   }
};

//When the page loads, check to see if it is already in fullscreen mode based on the pressence of the ms-fullscreenmode
//if the page is not a dialog add the marging and insert the menu
var bodyElement = document.body;
if (bodyElement != null) {
   if ($(bodyElement).hasClass('ms-fullscreenmode') && !window.location.search.match("[?&]IsDlg=1")) {
      $('#contentBox').attr('style', 'margin-top: 20px;');
      $('#contentRow').prepend(nav);
   }
}

 

Tip 5: Don’t put options in the quick launch that aren’t available elsewhere

The presumption is that if you are using a tablet you will stay focused on content. On our billing pages, the Generate Invoices link is only on the quick launch and therefore obscured to tablet users. We will move it in an upcoming update.

Tip 6: Turn off Minimal Download Strategy

This is not a concern if you are in an app web, but in host web scenarios, this feature created the most compatibility issues in the browsers we tested. Fortunately it is easy to detect and disable minimal download strategy with CSOM.
clientContext.Load(clientContext.Web.Features);
clientContext.ExecuteQuery();
var mds = clientContext.Web.Features.GetById(new Guid("87294C72-F260-42f3-A41B-981A2FFCE37A"));
if (mds != null)
{
   clientContext.Web.Features.Remove(new Guid("87294C72-F260-42f3-A41B-981A2FFCE37A"), true);
        clientContext.ExecuteQuery();
}

Tip 7: Size dialogs dynamically on open

The above tips dealt with width, but you also need to worry about height if you are using the dialog framework. When you show the dialog set the options based on the page’s natural height.
var options = {
   url: lps.WebUrl + '/FormsAndDialogs/Matter/NewMatter.aspx',
   title: 'New Matter',
   allowMaximize: false,
   showClose: true,
   height: 576,
};
SP.UI.ModalDialog.showModalDialog(options);

Then resize it by calling the following function from the page contained in the dialog.
function resizeDialogWorkspace() {
   //If the dialog is taller than the window make it shorter than the window
   if (window.innerHeight < jQuery('#s4-workspace').height()) {
      jQuery('#s4-workspace').height(window.innerHeight - 6);
   }
}

This is what the dialog looks like on a Nexus 7.