Getting Out of the Fixed Container

Most of today's websites use a wrapping container element on their pages – for good reason: it’s handy to have an element that surrounds the content, allowing it to shrink and expand to given breakpoints. But our beloved container can sometimes be a prison (and not even a golden one) when we want a full-screen element in our boxed layout. So the question becomes, how can we solve this before there is a prison break?


Out of the wrong path

If we’re working on an almost static website, we could just wrap everything except the full-width element; not a handy solution since we give away the benefits of using a container. Additionally, this is hard to apply in the strict enforced environment of a CMS where the layout is fixed and wrapped in a fixed container by default.

When trying to find a solution, one early approach could be to use negative margins that equal the positive margin on each side of the container. So if we have a container that takes 80% of the viewport, we can assume that the margins are 10%, and we may be tempted to give our full-width box a -10% margin on each side. The result clearly shows us that we failed, but why?


A common misconception

An element’s margins are calculated based on the width of its parent, so the 10% margin of the container is 1680px * 10% = 168px (in this case the resolution is 1680px) but if we set the same margin on the full-width box it will be (1680px * 80%) * 10% = 134,4px, and this is where our solution fails.

To calculate the right margin, we must use the ratio between the container and its margin, then we divide the viewport (100%) by the calculated ratio. In our case, it’s 80% / 10% = 8, and then 100% / 8 = 12,5% – that’s what our negative margin ought to be.

Copy
#container {
  width: 80%;
  margin: auto 10%;
}
.box-fullWidth { 
  margin-left: -12.5%; 
  margin-right: -12.5%; 
}

With a container width of 60% we would have: 60% / 20% = 3 and 100% / 3 = 33.33%:

Copy
#container {
  width: 60%;
  margin: auto 20%;
}
.box-fullWidth { 
  margin-left: -33.33%; 
  margin-right: -33.33%; 
}

So, problem solved? Sorry to say, but this solution only works if your container has a fixed width expressed as a percentage; the typical CMS container is something like: max-width: 1170px, which doesn’t let you calculate the margins.


A more flexible solution

So we need a more flexible solution that can be applied to the containers typically used in common CMSs, and we actually have it, thanks to CSS3 and the new Viewport Units. For someone who hasn’t ever heard of Viewport Units, they are powerful and nicely supported CSS3 units that refer to the width (vw) or the height (vh) of the viewport which is much more handy than percentages that refer to the element’s parent instead.

Back to our problem, the way to solve it is to push the edges of our full-width element towards the edge of the viewport, by means of a negative margin that equals the one we have between the element and the viewport, and with the help of Viewport Width (vh) and calc() we can reach our goal with ease:

Copy
.box-fullWidth { 
  margin-left: calc(-50vw + 50%); 
  margin-right: calc(-50vw + 50%);
} 

First, we move our box out of the page by half of the viewport (100vw = 100% of the viewport width), and then we push it back again by half of its width.


One last issue, with a reasonable solution

Unfortunately, there’s an issue with this solution that pops up unexpectedly in case the content of our box triggers a vertical scrollbar; with much dismay, we could see a horizontal scrollbar appearing as well. The reason for this is that the specification for the Viewport Units states that if the root element has overflow: auto (which is the default value) the scrollbars aren’t taken into account when computing the viewport width. So, has all of this struggle been in vain? No, there’s a pretty much acceptable solution for that: setting overflow-x to auto on the root level will prevent that unwanted behavior.

Copy
html,
body { overflow-x: hidden; }

Since the support for Viewport Units is overall good (starting from IE9), we can safely employ this solution; using overflow:hidden so it should not normally affect our layout’s behavior. Just note that if you are using jQuery’s scrollTop() you need to trigger it on document instead of on body or html.

Finally we can use CSS3 in its full glory: it seems obvious today but the time when you had to overload the website with hacks, fallback and polyfills was just yesterday. Lots of new properties are now at our disposal and, not only they’re changing the way we conceive layouts, but they help a lot in solving everyday CSS struggles. 

More great blog posts from Alessandro Lo Verde

  • Grill.rb and Grill.js: One part food, One part drink and whole lot of programming

    Suppose that you want to buy a grill to have a small party with a couple of friends, and then you realize that you’ve placed the wrong order since a monster sized grill arrives at your door. You probably want to send it back, trying to explain that the size was missing from the item’s description...

  • This is how business gets done: Nuremberg Airport and Scrivito

    There are good CMS's out there, and many are fine tools to make blogs, websites for small business and even for a medium-sized one; but can they handle a large website, with a lot of data interaction that comes from external sources? What comes up if you need to build an intranet as well?...

  • Get a better view: The Magic of Viewport Units

    Viewport Units are a fine addition to the new CSS3 properties and allow us to calculate dimensions according to the actual size of the viewport, instead of the parent element (as it’s always been so far). There is a new precious tool for better and easier responsiveness that leads the way to a...

  • Reverse Box Order on Mobile

    It’s a pretty common trend for many presentation websites to have a 3-column “feature box” where products or features are showcased. Since on mobile they would be squeezed too much, it’s a best practice to make these boxes 100% wide and place them one under each other, following the same order...

  • Let's Embrace CSS3 Calc()

    Powerful and widely supported, this handy CSS3 property helps save us from headaches when dealing with layout and box model. Back in the day, everything on the web was coded in pixels, but as the desire for flexible design arose, font sizes were frequently defined in ems and more recently in...

  • Web Typography Done Right

    Typography is often a mixed blessing for the web: Developers tend to overlook it since it does not play an important part in their interests, and designers sometimes are disappointed about the limits of the web, compared to print design. And yet typography is what truly makes the difference...