Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why isn't <body> expanding to fit its contents?

Tags:

css

I have a table that extends off the edge of the screen, but the body only gets as wide as the screen, causing the table to overflow it.

Demo: http://jsfiddle.net/6REkj/

<html>
    <head>
        <style>
            table { background-color: lime; }
            body { border: 2px solid blue; }
        </style>
    </head>
    <body>
        <table>
            <tr><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td></tr>
        </table>
    </body>
</html>

This is one of those things that make me think CSS is broken. I thought containing elements were supposed to expand to fit their contents.

Question 1: Why is it doing that?

Question 2: What should I do to get a margin between the table and the right edge of the page?

like image 441
Alan L Avatar asked Jan 27 '14 18:01

Alan L


People also ask

How do I make the width fit to content?

There are three ways to solve this problem which are listed below: By default case. Using inline-block property. Using fit-content property in width and height.

How can I make my height 100% work?

Height % is based on it's parent (so you have to set every element above the target element to 100%) , there are a few workarounds to this though. For instance you can set it to height: 100vh; This will create the element to be 100% of your window height. Or you can use px instead.

How do I wrap all content in a div?

If you've faced the situation when you need to wrap words in a <div>, you can use the white-space property with the "pre-wrap" value to preserve whitespace by the browser and wrap the text when necessary and on line breaks. Also, you'll need the word-wrap property.


3 Answers

It's very strange that the simplest solution hasn't been mentioned:

body {
  width: fit-content;
  min-width: 100%; /* because the content might only be a few words */
  box-sizing: border-box; /* because 100% + padding > 100% */
}

Unfortunately that doesn't work everywhere and it still requires prefixing. In Chrome (with Blink these days) that would be: -webkit-fit-content (-webkit- in Blink, weird).

like image 195
Rudie Avatar answered Nov 06 '22 09:11

Rudie


CSS isn't broken, the behaviour you are seeing is by design.

Some quotes from the link above:

The following constraints must hold among the used values of the other properties:

'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' = width of containing block

..

If 'width' is set to 'auto', any other 'auto' values become '0' and 'width' follows from the resulting equality.

From this I understand that block level elements have a default width of 100% of their containing block if all of the other properties are not set.

<body> is by default a block level element.

You could set float: left; or display: inline-block on body and it will grow with its content.

Here's a jsFiddle.

To answer question 2 (to get the result of the accepted answer without resorting to setting display: table on an element which isn't a table), you could do it this way:

CSS:

html {
    padding: 10px;
}
html, body {
    margin: 0px;
}
body {
    border: 2px solid blue;
    display: inline-block;
    min-width: 100%;
    box-sizing: border-box;
}
table, p {
    background-color: cyan;
}

Here's a jsFiddle.

like image 41
tom-19 Avatar answered Nov 06 '22 10:11

tom-19


if you set display:table; to body or html, it will allow to grow its width over the 100% of viewport. it will just expand like a table does :)

html {display:table;width:100%; /* need to set a width to 100%, wich means here a min-width since it is displayed with the same specifities thas has a table , it shrinks and expand according to its content */}

http://jsfiddle.net/6REkj/1/

other options :

  • display:inline-block;min-width:100%; on body : http://jsfiddle.net/6REkj/3/
  • position:absolute;min-width:100%; on html : http://jsfiddle.net/6REkj/4/

Edit nowdays, min-width:max-content would do . http://jsfiddle.net/bj4wk6m2/

like image 16
G-Cyrillus Avatar answered Nov 06 '22 10:11

G-Cyrillus