Building a Responsive Master Page To demonstrate the process of making a SharePoint master page Responsive using a Responsive framework or using the Device Channel feature, we will perform the following activities: Prepare the design for a Responsive framework Leverage the grid system to adapt the design to follow the grid system Use the Responsive framework to make the solution responsive Fix common Responsive issues with SharePoint Device Channels and responsive Prepare the Design for a Responsive Framework To prepare the design, you need to download the framework files, in this case the Bootstrap files, and add them to the solution. Download the Framework 1. Launch your browser and open http://twitter.github.com/bootstrap/ . 2. To download the entire Bootstrap framework, click the large Download button in the middle of the home page, or click Customize in the top navigation menu so that you can build your own download package. 3. On the Customize and Download page, click Toggle All found just to the right of “1. Choose components.” This will deselect all the components that are a part of Bootstrap so that we can select only those we want. For the bare minimum, select the following components: Scaffolding o Grid system o Layouts Responsive o Visible/hidden classes o Narrow tablets and below (<767px) o Tablets to desktops (767-979px) o Large desktops (>1200px) o Responsive navbar You might want to also include the following additional components. Scaffolding o Normalize and reset o Body type and links Components o Button groups and dropdowns o Navs, tabs and pills o Navbar o Breadcrumbs o Pagination JS components (all of them) 4. Next, scroll down to the jQuery plug-ins, and click Toggle all. We are not using any of the Bootstrap jQuery plug-ins right now, but you might want to include some of them so that you can use them throughout your web site build out. 5. Navigate to the bottom of the page and click Customize and Download. If you did not customize the Twitter Bootstrap download as documented earlier, you’d be adding a lot of unnecessary files and page weight to your project. Add a Framework to Your HTML Master Page Adding your framework assets, consisting of CSS style sheets, images, and JavaScript files, should follow the same process we use for uploading design files to SharePoint. 1. With Bootstrap, once you extract the framework package that you downloaded in the previous section to your workstation, open your SharePoint Master Page Gallery in your preferred method, be it Dreamweaver, SharePoint Designer, Windows Explorer, or others. 2. We recommend adding your framework assets to the same location as your custom HTML master page, in our case /_catalogs/masterpage/spectergroup. 3. Bootstrap files should be fairly easy to move into our branding solution folder structure, as our solution has a similar directory naming convention to how Bootstrap is structured (the css folder contains style sheets, the js folder contains JavaScript files, and the img folder contains images). Note, you might find it easier to match your branding solution to a framework’s directory structure rather than the other way around. Tip: Once you have uploaded your framework assets to your SharePoint Master Page Gallery, do not forget to approve and to publish a major version of all new files. Link an HTML Master Page to a Framework Now that we have the framework files added to SharePoint, we need to update our solution to reference the Responsive framework. 1. With a web editorsuch as Dreamweaver, open your HTML (i.e., /_catalogs/masterpage/spectergroup/SpecterGroup.html) for editing. 2. Add a <link> to your framework style sheet, bootstrap.min.css, which we placed in the /_catalogs/masterpage/spectergroup/css folder, somewhere in the <head> section of your HTML master page. Add the link of the framework before any other style sheets you might have already included. This allows you to override the framework if you need to, instead of having the framework override your custom styles. 3. With SharePoint, there are three ways in which SharePoint designers can add references to style sheets: a. Use the SharePoint:CssRegistration Control - The SharePoint:CssRegistration server control generates a <link> element into the resulting HTML page that applies the specified style sheet. This has benefits over the HTML markup, as it gives you control over the order in which a CSS style sheet is applied (before or after other CSS files). Markup for SharePoint:CssRegistration Control <!--MS:<SharePoint:CssRegistration Name="/_catalogs/masterpage/spectergroup/css/bootstrap.css" runat="server">--> <!--ME:</SharePoint:CssRegistration>--> <!--MS:<SharePoint:CssRegistration Name="/_catalogs/masterpage/spectergroup/css/bootstrap.css" After="Themable/corev15.css" runat="server">--> <!--ME:</SharePoint:CssRegistration>--> <!--SPM:<SharePoint:CssRegistration Name="/_catalogs/masterpage/spectergroup/css/bootstrap.css" runat="server" />--> <!--MS:<SharePoint:CssRegistration Name="&lt;% $SPUrl:~sitecollection/_catalogs/masterpage/spectergroup/css/bootstrap.css %&gt;" After="Themable/corev15.css" runat="server">--> <!--ME:</SharePoint:CssRegistration>--> b. Use an Alternative CSS URL - set one Alternate CSS style sheet via Site Settings (Site Settings -> Look and Feel -> Master Page). This approach allows site administrators to lock down one specific style sheet, but only one style sheet. This is not practical when the customizations to the design are not just style based, typically covered by a CSS file, versus structural changes, which is where master pages and page layouts come into play. c. Use the HTML <link> Tag - The HTML <link> tag is generally the easiest way to link to a style sheet with HTML master pages. It does not take advantage of any benefits that SharePoint’s server tags provide such as caching, control over cascading, or access to dynamic CSS file paths. On the plus side, SharePoint will handle the directory path for us assuming that the style sheets are in a subdirectory of the HTML master page. <link rel="stylesheet" href="css/bootstrap.min.css" /> 4. In our HTML master page we will find our other links to style sheets and add our new link just before them. <head> <!--beginning removed for simplicity--> <!--DC:Specter Group Bootstrap Version--> <meta name="description" content="" /> <!--Our framework stylesheet--> <link rel="stylesheet" href="css/bootstrap.css" /> <link rel="stylesheet" href="css/bootstrap-responsive.css" /> <!--originally included stylesheets--> <link rel="stylesheet" href="css/superfish.css" /> <link rel="stylesheet" href="css/nivo-slider.css" /> <link rel="stylesheet" href="css/isotope.css" /> <link rel="stylesheet" href="css/elements.css" /> <link rel="stylesheet" href="css/style.css" /> <!-- Modernizr enables HTML5 elements &#38; feature detects for optimal performance. Include html5shiv 3.6. Our version is a custom build. Create your own custom Modernizr build: www.modernizr.com/download/ --> <script src="js/modernizr-2.6.2.custom.js">//<![CDATA[//]]> </script> <!--remaining head bloc removed for simplicity--> </head> Leveraging the Grid System With the framework reference in place, we are now ready to change our design files to take advantage of the Responsive framework. Bootstrap, like many other CSS frameworks, takes advantage of grids, which allow you to stack content elements on top of one another as well as next to each other. This grid system provides web designers with a structured approach to design. Grid-Based Design The way any grid system works is that containers are stacked horizontally. Each single container contains one or more rows and each row contains one or more columns. What really gives the grid-based design flexibility is that you can include a container inside a column. Most grid frameworks include this functionality so now a column can have its own set of rows and columns. With Bootstrap’s fixed-width grid system, each row container allows up to 12 columns with a total width of 940 pixels. Each column’s width is 60 pixels and there’s 10 pixels of padding on either side of each column, thus 20 pixels of padding between any two columns. Note, the fixed container is 940 pixels wide, with the Bootstrap responsive features, the grid will adapt between 724 and 1,170 pixels wide. For viewports less than 767 pixels wide, the columns instead stack vertically and become fluid to fill up the entire width of the viewport. Basic Bootstrap Grid Let’s implement a grid using CSS. 1. Create a div container that will hold all your markup inside of it. This typically is in the form of a primary div such as <div class="container">…</div>. 2. Inside the div container, start creating your markup using a series of row containers. 3. Within each row, create one or more span (column) div containers as well as nested rows to break a column into even more rows and columns. 4. Given that Bootstrap uses a 12-column grid, make sure that each row you create, including nested rows with columns, has a total of 12 spans (columns). Example: Create a simple Bootstrap-driven grid that has two rows. The first row will have one column that spans the length of 12 column units. The second row will have two columns, the first column spans the length of 3 column units and the second column spans the length of 9 column units. <div class="container"> <div class="row"> <div class="span12"> Row 1 - column 1 </div> </div> <div class="row"> <div class="span3"> Row 2 - column 1 </div> <div class="span9"> Row 2 - column 2 </div> </div> </div> Add Bootstrap to an HTML Master Page Using the sample Specter Group solution, let’s add Bootstrap to our HTML master page. Divide an HTML Master Page into Rows and Columns 1. Divide the Specter Group design visually into major components: a. Header: Contains the Specter Group logo, tagline, search, and the social media dropdown list. b. Top Navigation: Contains the home button, navigation items, registration, and login icons. c. Main Content: This will vary based on the page layout that we are on. d. Footer: Contains the About Us, Twitter News, Recent Posts, Copyright, and Legal related links. 2. Go through each major component’s div container and add <div class="container">…</div> around the content. (see the following sections for detailed steps) 3. For each row, you’ll want to split it into columns, as long as the number of columns totals 12 for each row. (see the following sections for detailed steps) 4. Before we add a grid framework, here is a simplified version of the HTML structure of our master page. We will walk through adding Bootstrap to each primary section in the master page. Note, do not touch the SharePoint provided s4-workspace or s4-body-Container <div>’s, as all SharePoint pages will need those. Also, leave the HTML5 tags, <header>, <nav>, and <footer> as larger wrappers. This will not cause a problem with our grid as long as we leave the width set to “auto,” which is the default, for these three tags. <body> <div id="s4-workspace"> <div id="s4-bodyContainer"> <!-- HEADER --> <header> <!-- header wrapper --> <div class="wrapper cf">...</div> <!-- ENDS header wrapper --> </header> <!-- ENDS HEADER --> <!-- nav --> <nav id="topnav"> <!--navigation wrapper--> <div class="wrapper cf">...</div> <!--end navigation wrapper--> </nav> <!-- ends nav --> <!-- MAIN --> <div role="main" id="main"> <!--Main content wrapper--> <div class="wrapper cf">...</div> <!--end Main content wrapper--> </div> <!-- ENDS MAIN --> <footer> <!-- wrapper --> <div class="wrapper cf"></div> <!--end wrapper--> <!-- bottom footer--> <div class="footer-bottom"> <div class="wrapper cf"></div> </div> <!--end bottom footer--> </footer> </div> </div> </body> Bootstrap and the Header 1. Find the <header> block near the top of the HTML master page document. We can see it has one primary wrapper <div>. 2. Change the class attribute value of the first <div> container, from wrapper cf to container to provide for our fixed container. 3. For each container, we must have a row container, so we will add a new <div>, <div class"row"> right after the <div class="container">. We’ll want to close the row container by adding a </div> before the end of the container <div>. 4. Now that we’ve wrapped the logo, tagline, searchbox, and social containers in Bootstrap’s container and row components, it’s time to wrap each of the smaller components into columns. The logo and tagline will be wrapped around by <div class="span8"> container and the searchbox will be wrapped around by <div class="span4">. <header> <div class="container "> <div class="row "> <div class="span8"> <div id="logo"> <!--logo snippet--> </div> <div class="tagline"> <!--h2 tag lines--> </div> </div> <div class="span4"> <div class="searchbox"> <!--search box snippet--> </div> </div> <div class="social cf"> <!--social icons--> </div> </div> <!--end row--> </div> <!--end container--> </header> Bootstrap and Navigation 1. The top navigation should be wrapped around in a single container, with a single row and span (12 column units wide). To leverage Bootstrap framework, we need to change the class attribute value of the first <div> container, from wrapper cf to container to provide for our fixed container. 2. For each container, we must have a row container, so we will add a new <div>, <div class"row"> right after the <div class="container">. We’ll want to close the row container by adding a </div> before the end of the container <div>. 3. We also need to add more Bootstrap code to utilize Bootstrap Navbar components. We will learn more about Bootstrap Navbars in a later stage. Top Navigation code before Bootstrap integration: <nav id="topnav"> <div class="wrapper cf"> <!--nav snippet--> <div class="nav"> <!--Navigation List--> </div> <!--end nav snippet--> <!--MS:<SharePoint:SPSecurityTrimmedControl runat="server" AuthenticationRestrictions="AnonymousUsersOnly">--> <div class="site-access cf"> <!--Site access links--> </div> <!--ME:</SharePoint:SPSecurityTrimmedControl>--> </div> </nav> Top Navigation code after Bootstrap integration with Bootstrap Navbar: <nav id="topnav"> <div class="container "> <div class="row "> <div class="span12"> <div class="navbar navbar-inverse"> <div class="navbar-inner"> <div class="container"> <a class="btn btn-navbar" data-toggle="collapse" data-target=".navcollapse"> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </a> <div class="nav nav-collapse collapse"> <!--nav snippet--> </div> <!--end class nav--> </div> <!--end container--> </div> <!--MS:<SharePoint:SPSecurityTrimmedControl runat="server" AuthenticationRestrictions="AnonymousUsersOnly">--> <div class="site-access cf"> <!--site access links--> </div> <!--ME:</SharePoint:SPSecurityTrimmedControl>--> </div> </div><!--end span 12--> </div> <!--end row--> </div> <!--end container--> </nav> Bootstrap and Main Content 1. The Main Content of a particular page will be defined by page layouts or system pages that SharePoint provides for us. Our HTML master page only needs to provide us one primary container, row, and column. Main content code before Bootstrap integration: <div role="main" id="main"> <div class="wrapper cf"> <!--main content placeholder--> </div> </div> Main content code after Bootstrap integration (without Quick Launch on the left): <div role="main" id="main"> <div class="container "> <div class="row "> <div class="span12"> <!--main content placeholder--> </div> </div> </div> </div> 2. For pages that require the Quick Launch for vertical navigation (example: system pages), we need to divide the “main” row into two columns, the left for the Quick Launch and the right for the main content placeholder. Main content with an additional column for the Quick Launch <div role="main" id="main"> <div class="container "> <div class="row "> <div class="span3"> <!--Vertical Navigation Snippet--> </div> <div class="span9"> <!--main content placeholder--> </div> </div> </div> </div> Bootstrap and a Footer As we have seen in our design, the Footer is broken into two rows, the top row having three columns and the second row having two columns. We need to split up the Footer into smaller chunks. 1. Make sure that all content inside the Footer is wrapped inside a container. The design already has two places where there exists a <div> container with two class attributes wrapper and cf. Replace both of these with a CSS class container to take advantage of Bootstrap’s grid system. 2. Now break up the rest of the footer design into two rows and columns. We’ll do that for each row of content and further define column spans (where applicable). 3. Remove the unordered lists but keep the tags for the content, and add spans, <div="span4">. 4. For the second footer, add <div class="span6"> around each container. Footer code before Bootstrap integration: <footer> <!-- wrapper --> <div class="wrapper cf"> <ul class="cols cf"> <li class="col"> <div class="col-block"> <!--left column--> </div> </li> <li class="col"> <div class="col-block"> <!--middle column--> </div> </li> <li class="col"> <div class="col-block"> <!--right column--> </div> </li> </ul> <!-- ENDS columns --> </div> <!--end wrapper--> <!-- bottom footer--> <div class="footer-bottom"> <div class="wrapper cf"> <div class="copyright"> <!--copyright--> </div> <div class="sitemap"> <!--sitemap list--> </div> </div> </div> <!--end bottom footer--> </footer> Footer code after Bootstrap integration: <footer> <div class="container "> <div class="row "> <!--columns--> <div class="span4"> <!--left column--> </div> <div class="span4"> <!--middle column--> </div> <div class="span4"> <!--right column--> </div> <!-- ENDS columns --> </div> <!--end row--> </div> <!--end container--> <!-- bottom footer--> <div class="footer-bottom"> <div class="container "> <div class="row "> <div class="span6 copyright"> <!--copyright--> </div> <div class="span6 sitemap"> <!--sitemap list--> </div> </div> </div> </div> <!--end bottom footer--> </footer> Make It Responsive Now that we have referenced Twitter Bootstrap files in our new design and converted each of the major containers to leverage Bootstrap, let’s start making the site responsive. The Viewport Meta Tag Before we turn on the responsive grid, we need to set up the viewport properly. We already know that the viewport is the screen or monitor on which we are viewing a site. For desktop browsers, your viewport is your browser window; with mobile devices, your viewport is normally the full width of the given screen. Traditionally on mobile devices, a mobile device will assume that a given page is not mobile ready and thus should be rendered as if on a desktop. This likely would be in the 960-pixel-wide range, but zoomed out so that the user can see the entire site, even if it is extremely small. The user can then zoom in on a particular part of the page. A new meta tag has been provided that most mobile devices recognize which gives us the ability to tell a device to set the site width to the viewport’s native width, start the zoom at 100% and pan as necessary. 1. <meta name="viewport" content="width=device-width, initial-scale=1.0" /> Add this tag to our HTML master page <head> section Viewport Meta tag in HTML Master page <head>: <!DOCTYPE html[]> <html class="no-js" lang="en"> <head> <meta http-equiv="X-UA-Compatible" content="IE=10" /> <meta name="description" content="" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <!--CS: Head Contents Snippet--> <!--Our stylesheets--> <link rel="stylesheet" href="css/bootstrap.css" />--> <!-- Our scripts--> <script src="js/modernizr-2.6.2.custom.js">//<![CDATA[//]]> </script> <!--[if gte mso 9]> <xml> <mso:CustomDocumentProperties> <!--Document properties--> </mso:CustomDocumentProperties> </xml> <![endif]--> </head> <!--rest of HTML MasterPage--> Media Queries By default, Bootstrap includes targeted media queries starting with smaller smart phones and working its way up to a large display, viewports that are 1,200 pixels across and wider. Each media query changes the size of the columns to reflow the layout to something more appropriate for the viewport. Viewports Bootstrap Responsively Supports Out of the Box Label Phones Phones to tablets Portrait tablets Default Large Display Layout Width Column Width Gutter Width 480px and below Fluid columns, no fixed width 767px and below Fluid columns, no fixed width 768px and above 42px 20px 980px and up 60px 20px 1,200px and up 70px 30px 1. If there is a need to develop custom media queries, you need to add the following to your custom stylesheet to target specific viewports: /** Large Desktop */ @media (min-width: 1200px) { … } /** Portrait tablet to landscape and desktop */ @media (min-width: 768px) and (max-width: 979px) { … } /** Landscape phone to portrait tablet */ @media (max-width: 767px) { … } /** Landscape phone and lower */ @media (max-width: 480px) { … } 2. To test the responsive site design in multiple devices can be time consuming. You can resize your browser window on your development workstation with any modern browser including Internet Explorer 9 and above. If you did everything right, your site should shrink with your browser window. 3. Another recommended way for testing is to use the Responsive Design View (Ctrl+Shift+M) available in current versions of Firefox. a. To find this, load your page in Firefox and go to Tools -> Web Developer -> Responsive Design View or press Ctrl+Shift+M. b. Your page will now load in a window within your browser window. c. At the top left you can get the exact dimensions of a viewport on which you would like to preview your site. At this point, we have added all the responsive components to our solution. The Specter Group site should look like the following at 960 pixels, 768 pixels, and 320 pixels wide: Device Channels and Responsive Web Design Device channels are a new feature added to SharePoint 2013, originally designed as an updated approach to developing mobile-friendly sites. Device channels allow us to map devices and browsers to appropriate master pages. For each device channel, we can define devices that are applicable to it by adding device inclusion rules with user agent substrings, and then we associate a master page with each device channel. Device channels are especially useful when we need to define a web site rendering that is optimal for a specific device. If device channels are designed to provide mobile views, you might ask yourself why we are bothering with responsive web design. Here are a few reasons: A device channel is mapped to devices (i.e., user agents). What do we do with the ever increasing number of devices? How do we manage that list? There are no standards for viewport widths, so we might have to create a device channel for so many different viewport widths it could quickly become unmanageable. We need to maintain a master page for each device channel. One branding effort can be difficult enough to build, test, debug, and maintain; adding channels means multiplying that effort. When to use Device Channels There could be many reasons to use Device Channels, here are two possible reasons why device channels might come in handy. Remember that device channels are mapped to the user agent and not an actual device. This means we can map to not just an iPhone, but to a specific browser version such as IE 7 or IE 8 regardless of the device. If a large percentage of your users are accessing the web site using a specific device, say a Surface Pro, then you could create a solution that includes two device channels, one specifically for Surface Pro users and a second for rest of the visitors. This first device channel might not need to be responsive, nor would you have to provide much client-side feature detection because you know what features are and are not available. Having a device channel specifically created for a device might open the doors to a truly unique experience for those visitors. Device channels could also be leveraged to provide a lighter or less feature-rich version of a site design that works well in, say, Internet Explorer 8 or older. This way you could create a device channel mapped to an HTML5 master page for most visitors with modern browsers that is responsive and a second device channel just for older versions of IE that does not use HTML5, CSS3, and maybe even limits JavaScript as well. Create a Device Channel Let’s walk through how to create a device channel in SharePoint 2013. 1. Browse to the Design Manager in a browser by clicking the Settings icon and then selecting Design Manager 2. From the left navigation menu, select the menu item 2. Device Channels 3. After the Manage Device Channels page loads, click Create a Channel, found just under the main page title, to create a new device channel. 4. The New Device Channel dialog box will appear. You will need to enter information related to your custom device channel: a. In the Name text box, enter a name for the device channel. b. In the Alias text box, enter an alias for the device channel. c. In the Description text box, enter a brief description of the devices or browsers that the channel will capture. d. In the Device Inclusion Rules text box, enter the user agent substrings for the channel. A request for a web page will use this channel if any of the strings that you provide match any part of the user agent string of the requesting agent. As an example, Windows Phones have user agent strings that contain the substring “Windows Phone”. If you wanted a device channel for all Windows Phones, a Device Inclusion Rule need only contain the rule, “Windows Phone” and not the entire long user agent, Mozilla/5.0 (compatible; MSIE 9.0; Windows Phone OS 7.5; Trident/5.0; IEMobile/9.0). e. If you are ready to make the channel available to render pages, select the Active check box. f. Once you have entered all of the required information, click Save to save your new device channel. Assign a Master Page to a Device Channel Once a device channel has been configured and a master page has been created that a particular device channel should use, it is time to assign the master page to the device channel. 1. Open your Site Settings page in a browser and under Look and Feel click Master Page. 2. On your Site Master Page Settings page, next to Site Master Page, you should see each device channel you created. You can now set any valid, published master page to each device channel. Notice that you can only set a specific site master page to each device channel, and your system master page will be the same for all devices. This means that all system pages and other pages that use the system master page will always use the same master page. Testing with User-Agent String When a browser requests a web page from a web server, a browser will send along a user-agent (UA) string that identifies the browser type and version to the web server. The chosen UA string will be sent across the network as a header in every request. For development and testing purposes, changing your user-agent string could be very beneficial and there are a variety of browser-specific tools you can use to accomplish this. As an example, in Internet Explorer 10, we can change the user-agent string for testing. 1. In Internet Explorer 10, we can change the user-agent string by enabling the Developer Toolbar by pressing F12 and then selecting a different browser mode from Tools -> Change user agent string