Question

I have a page which contains a dynamically-generated table. The number of columns of this table and the width of their content is determined at page generation time, but can be sufficiently large that the table exceeds the width of the window.

When this happens, the width of the body element does not expand to contain its contents, but is restricted to the width of the window. As such, all other descendent elements (with the exception of the table) also have a maximum width equal to the width of the window:

__________________________ window bounds
| BODY ELEM              |
| ______________________ | 
| |     HEADER ELEM    | |
| |____________________| |
|                        |
| ______________________ |
| |      DIV#main      | |
| | __________________________________________________
| | |    ELEMENT WHICH IS WIDER THAN WINDOW          |
| | |________________________________________________|
| |____________________| |
|                        |
| ______________________ |
| |     FOOTER ELEM    | |
| |____________________| |
|________________________|

This means when scrolling horizontally, the other block-level elements stop prematurely (their background colours do not expand, spoiling the look of the page).

Here is a jsFiddle showing the problem. Notice how the yellow block in the results window expands to the right, but the brown, white and blue blocks do not.

I'm looking for a pure CSS method of solving this problem.

The closest I've come without resorting to altering the document structure at all is this:

body {
  min-width: -webkit-min-content;
  min-width: -moz-min-content;
  min-width: min-content;
}

However, "min-content" is not supported by IE at all. Does anyone have a cross-browser, pure CSS solution to this issue?

For completeness (in case people can't see the jsFiddle), here is some code displaying the problem:

<!DOCTYPE html>
<html>
  <head>
    <style type="text/css">

    * {margin:0;padding:0;}

    body {
        background-color: #888;
        /* Adding the two lines below fixes the problem for webkit and moz.  But IE does not support min-content.
        min-width: -webkit-min-content;
        min-width: -moz-min-content;
        */
    }

    header {
        background-color: #321;
    }

    header nav {
        padding: 10px;
        color: #FFF;
    }

    footer {
        padding: 10px;
        color: #ccc;
        background-color: #123;
    }

    #main {
        padding: 16px;
        background-color: #FFF;
    }

    #wideContent {
        background: #FF0;
        width: 4800px; /* In reality, this will vary at runtime, so I cannot set an explict width on the body */
    }

    table {
        border-collapse: separate;
        border-spacing: 0px;
        border-color: #808080;
        border-style: solid;
        border-width: 1px;
        border-bottom-width: 0;
        background-color: #FFF;
    }

    td, th {
        border-color: #808080;
        border-style: none;
        border-width: 0;
        border-bottom-style: solid;
        border-bottom-width: 1px;
        padding: 5px 10px;
        min-width: 100px;
    }

    </style>
  </head>
  <body>
    <header>
      <nav>Header</nav>
    </header>
    <div id="main">
      <div id="wideContent">
        <p>Content here will be a table with a very large number of columns.</p>
        <p>The content and width of the table is not known beforehand, so cannot be preset anywhere in CSS.</p>
      </div>
    </div>
    <footer>
      <p>Footer</p>
    </footer>
  </body>
</html>
Was it helpful?

Solution

I just added following CSS. And it works.

body {
    float: left;
    min-width: 100%;
}

OTHER TIPS

This isn't a solution to exactly the question you asked, but a neat option would be to add overflow:auto to #main, so it can scroll internally without breaking the layout.

#main {
    overflow: auto;
}

Demo: http://jsfiddle.net/dZS4V/

This is an approach:

#wideContent {
    background: #FF0;
    width: 4800px; /* In reality, this will vary at runtime, so I cannot set an explict width on the body */
    max-width: 100%;
}

The wideContent div will adjust to the width of the window.

After further fiddling, I've come up with a solution which involves adding an additional wrapper element to the three section elements. This may be useful to others with the same problem, however, I'm not going to mark this as accepted (yet) because I'm still keen to see if there's a CSS solution which doesn't involve modifying the HTML at all.

Anyway, this solution is to wrap the header, footer and div#main elements in a new div.layout-row element and add the following CSS:

    body {
        display: table;
        border-spacing: 0;
        min-width: 100%;
        box-sizing: border-box; /* Only needed if your body has padding or borders */
        margin: 0;
    }

    div.layout-row {
        display: table-row;
    }

    header, footer, div#main {
        display: table-cell;
    }

Seems to work in Chrome, FF and IE. Demo here.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top