Skip to content

Instantly share code, notes, and snippets.

@amelieykw
Last active April 9, 2018 09:30
Show Gist options
  • Save amelieykw/9316fb305ef831a278ff1bb7b5bc46bd to your computer and use it in GitHub Desktop.
Save amelieykw/9316fb305ef831a278ff1bb7b5bc46bd to your computer and use it in GitHub Desktop.
[The Best Way to Implement a “Wrapper” in CSS]#wrapper #CSS #HTML #CSS-tricks

Original Website

  • "Wrapper" vs "Container"
  • width vs max-width
  • Additional Padding
  • Which HTML Element to Choose
  • Using the <body> tag vs. Using an additional <div>

Sometimes the first bit of HTML we write in a new document is an element that wraps everything else on the page.

The term wrapper is common for that. We give it a class, and that class is responsible for encapsulating all visual elements on the page.

Before we dive into it, let's first examine the difference between the "wrapper" and the "container".

I believe there is a difference between wrapper and container elements.

  • container is generally used for structures that can contain more than one element.
    • One that sometimes necessary to implement a behavior or styling of multiple components.
    • It serves the purpose of grouping elements both semantically and visually.
    • E.g. Bootstrap has "container classes" that house their grid system or contain various other components.
  • A wrapper, on the other hand, is something that wraps around a single object to provide more functionality and interface to it.
    • it's common to think of a <div> that contains all the rest of the HTML of the document
    • Wrappers are also used for things like applying a sticky footer

The terms wrapper and container can also mean the same thing depending on the developer and what they intend.

The best advice is usually to implement whatever makes the most sense to you.

Here's an example of a general page wrapper:

/**
 * 1. Centers the content. Yes, it's a bit opinionated.
 * 2. See the "width vs max-width" section
 * 3. See the "Additional Padding" section
 */
.wrapper {
  margin-right: auto; /* 1 */
  margin-left:  auto; /* 1 */

  max-width: 960px; /* 2 */

  padding-right: 10px; /* 3 */
  padding-left:  10px; /* 3 */
}

width

Setting the width of a block-level element will prevent it from stretching out to the edges of its container (good for things like readable line lengths).

Therefore, the wrapper element will take up the specified width.

The problem occurs when the browser window is narrower than the specific width of the wrapper. That will trigger a horizontal scrollbar, which is almost always undesirable.

max-width

Using max-width instead, in this situation, is better for narrower browser windows.

This is important when making a site usable on small devices.

Here's a good example showcasing the problem.

HTML

<div class="width">This div element has width: 960px;</div>
<br />

<div class="max-width">This div element has max-width: 960px;</div>
<br />

<strong>Note:</strong> Drag the browser window to smaller than 960px wide, to see the difference between the two divs!

CSS

/**
 * The problem with this one occurs
 * when the browser window is smaller than 960px.
 * The browser then adds a horizontal scrollbar to the page.
 */
.width {
    width: 960px;
    margin-left: auto;
    margin-right: auto;
    border: 3px solid #73AD21;
}

/**
 * Using max-width instead, in this situation,
 * will improve the browser's handling of small windows.
 * This is important when making a site usable on small devices.
 */
.max-width {
    max-width: 960px;
    margin-left: auto;
    margin-right: auto;
    border: 3px solid #73AD21;
}

/**
 * Credits for the tip: W3Schools
 * https://www.w3schools.com/css/css_max-width.asp
 */

Result

In terms of responsiveness, max-width is the better choice!

I've seen a lot of developers forget one particular edge case. Let's say we have a wrapper with max-width set to 980px.

The edge case appears when the user's device screen width is exactly 980px. The content then will exactly glue to the edges of the screen with no breathing room left.

The "no breathing room left" problem

We usually want a bit of padding on the edges.

That's why if I need to implement a wrapper with a total width of 980px, I'd do it like so:

.wrapper {
  max-width: 960px; /* 20px smaller, to fit the paddings on the sides */

  padding-right: 10px;
  padding-left: 10px;

  /* ...  */
}

Therefore, that's why adding padding-left and padding-right to your wrapper might be a good idea, especially on mobile.

Or, consider using box-sizing so that the padding doesn't change the overall width at all.

A wrapper has no semantic meaning.

It simply holds all visual elements and content on the page. It's just a generic container. In terms of semantics, <div> is the best choice. The <div> also has no semantic meaning and it just a generic container.

One might wonder if maybe a <section> element could fit this purpose. However, here's what the W3C spec says:

The <section> element is not a generic container element.

When an element is needed only for styling purposes or as a convenience for scripting, authors are encouraged to use the div element instead.

A general rule is that the section element is appropriate only if the element's contents would be listed explicitly in the document's outline.

The <section> element carries it's own semantics.

It represents a thematic grouping of content. The theme of each section should be identified, typically by including a heading (h1-h6 element) as a child of the section element.

Examples of sections would be chapters, the various tabbed pages in a tabbed dialog box, or the numbered sections of a thesis.

A Web site's home page could be split into sections for an introduction, news items, and contact information.

It might not seem very obvious at first sight, but yes! The plain ol' <div> fits best for a wrapper!

It's worth mentioning that there will be some instances where one could use the <body> element as a wrapper.

The following implementation will work perfectly fine:

body {
  margin-right: auto;
  margin-left:  auto;
  max-width: 960px;
  padding-right: 10px;
  padding-left:  10px;
}

And it will result in one less element in your markup because you can drop that unnecessary wrapper <div> this way.

However, I wouldn't recommend this, due to flexibility and resilience to changes. Imagine if on a later stage of the project any of these scenarios happen:

  • You need to enforce a footer to "stick" to the end of the document (bottom of the viewport when the document is short). Even if you can use the most modern way to do it - with flexbox, you need an additional wrapper <div>.
  • You need to set the background-color of the whole page. Normally, whatever background you set on the <body> will behave as if it was set on the <html> element should it not already have a background. Just a weird thing in CSS. But if your <html> element does already have a background, and you set the body to something else, and the body has any kind of spacing constraint, backgrounds will get weird. It's a tricky thing.

I would conclude it is still best practice to have an additional <div> for implementing a CSS wrapper. This way if spec requirements change later on you don't have to add the wrapper later and deal with moving the styles around. After all, we're only talking about one extra DOM element.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment