Steve Davis
Faux Full Width Sections (CSS)

A relevant design trend on the web is the long scroller. Long scrollers are pages with content organized vertically, typically broken into full width sections designated by visually different backgrounds (color or images). This format supports the easiest and most ergonomic movement on a mobile device, the swipe. It works equally as well on a laptop with a touchpad, or desktop with a mouse that has a decent scrollwheel. I am a big supporter of this trend for the right applications, and in the limited web design that we do here at Bio::Neos, we at least suggest to our clients that they consider this design when we discuss any informational website projects (even our more complex web applications often will need some informational website to describe the project).

Background

This article describes a problem that we have encountered in these types of projects when content organization doesn't always lend itself to this full width section design (with no space between the element and the edge of the browser window). More specifically, we have encountered this when building a Drupal page using a Zen subtheme as a starting point for theme design. Our own homepage is designed using this technology and technique.

:N Homepage
Bio::Neos Long Scroller Homepage

The standard Zen layout can be fixed or liquid, but in either case there is the following organization:

Block Regions in Zen
Block Region Demonstration for basic Drupal Zen theme

The yellow regions were designed as content locations by the Zen designers. They are generally implemented with HTML5 elements (header, footer, article, section) and some <div>'s where needed. As these are all mainly block-level elements, achieving the full width content sections looks possible if we 1) disable or don't use the sidebar regions, and 2) remove the padding from the Header, Navigation Bar, Footer, and Content

<div>'s with our theme's CSS. It isn't as straightforward as that.

There is another component to the standard Zen layout, the #page <div>.

#page div in Zen
The #page <div>

This <div> surrounds most of the page elements. Why? To avoid excessively long lines of text when viewed on an ultra-wide monitor. By default, this element has a max-width: 1200px; setting.

#page div max-width
The max-width setting on the #page <div>

Given the direction of monitor design such as the Apple 27" Thunderbolt display (2011) an increasing number of pixels can be expected to be available to web browsers (in this case 2560x1440). This obviously will continue into the foreseeable future, just look at 4K video (3840x2160 pixels). To a certain extent, a large amount of dead space surrounding your content can be equally as bad, but in general I do support having this element surrounding our content to allow for easily restricting the width of our text, while keeping things centered with margin: auto.

What does this mean for our full-width sections? Well, once that max-width comes into play, our sections no longer grow with the browser window. To address this limitation, we either have to ditch the #page <div> (or unset the max-width) or use what I like to call faux full width sections. The following technique is a CSS-only approach to "faking" the full width sections without dropping the #page <div>, and is supported by the current versions of all the major browsers, and the previous 2 versions back as of this writing.

Faux Full Width Sections

Using CSS only, we can trick browsers into displaying what looks like a full-width section even though it has a container element that isn't full width. This trick does have some limitations and should not be used in all situations, but for those that want to maintain that default Zen structure in Drupal, they may find this useful just as we have.

Note:The examples below show what this would look like with vanilla HTML / CSS (no Drupal/Zen involved). You can accomplish this approach by modifying the Zen theme templates, as noted.

We start by defining a block level element to represent our section within the content <div> (Note: this same approach works equally as well for the header and footer).

<div id="page">
  <section class="full color1">First Section</section>
  <section class="full color2">Second Section</section>
</div>

Now within our CSS, we must trick the browser into displaying the section extended out to the left and right of its boundaries. We achieve this with a combination of padding and negative margins.

body
{
  margin: 0;
}
#page
{
  max-width: 900px;
  margin: auto;
}
.full
{
  padding-left: 10000px;
  margin-left: -10000px;
  padding-right: 10000px;
  margin-right: -10000px;
  min-height: 100px;
}
.color1
{
  background-color: #918FB4;
}
.color2
{
  background-color: #3BCBAF;
}

This combination results in a content box that begins in the expected location, but things like background-color and background-image get extended outside of the content box regardless of the size of the containing element. Hooray! Except — we still have one problem: page width. Even though the content is where we want things, the browser now has a nasty horizontal scrollbar. Whoops.

Horizontal scroll
Example page viewed with a 1000px browser window, note horizontal scrollbar

We address the page width using overflow-x: hidden. However, there is one quirk we must account for: the mobile viewport. Often the <body> would be declared as the viewport (and is the case in Drupal's Zen) and that would be the element where we would want to assign the hidden overflow attribute. The reason this is a problem: mobile browsers ignore overflow: hidden on the viewport. Why? Who knows, but we definitely want to address that or else our page will look horrible on a mobile browser.

The solution is simple, we introduce another wrapper immediately inside of the <body> and give it the overflow property. Piece of cake!

With regard to using Zen on Drupal, this is done with a simple change to the page template. Simply copy page.tpl.php from the Zen theme's templates/ directory, into your theme's templates/, and modify it to add this element. The <div> tag should surround that entire template file. Once again, the code example below is showing how to do this with straight HTML / CSS.

.page-wrapper
{
  overflow-x: hidden;
}
<html>
<head>
  <meta name="viewport" content="width=device-width">
</head>
<body>
  <div class="page-wrapper">
    <div id="page">
      <section class="full color1">First Section</section>
      <section class="full color2">Second Section</section>
    </div>
  </div>
</body>
</html>

The resulting page now looks as we intended, as long as we take care not to introduce any items inside of our sections that flow outside of our #page container, as they will be cut off by the hidden horizontal overflow (probably wouldn't be what was intended anyway).

Horizontal scroll
Final example should work on most modern browsers, even mobile

I hope this write-up helps someone other than myself. It really is a pretty straightforward technique although only useful in those situations where you are unwilling or unable to change the page organization so that there is not a full page container. How generally useful that is, I don't really know, but I have found myself using this a few times along the way so I thought it was worthwhile to write it up.

Note: I have to comment that the same technique can be used to make multiple columns look like they are all the same height. That use case might even be more generally applicable than the full width sections.