Why isn't <body> expanding to fit its contents? - 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?

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/

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).

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.

The only solution for this is to have a vertical scrollbar.
It can be achieved with an additional div, wrapping the table.
This would be the css:
body { border: 2px solid blue; }
table, p { background-color: cyan; width: 100%; word-wrap:break-word;}
div { width: 100%; overflow-x: auto;}
If you would only have the p-Tag, the attribute word-wrap:break-word; helps.
You can also move the paragraph outside the div, which allows you to see the whole content without scrolling.
See the fiddle for a working sulution:
http://jsfiddle.net/WrbpJ/
If you prefer scrolling the whole page, and not only the div, this can be used:
body { border: 2px solid blue; display: table;}
See http://jsfiddle.net/sGH4t/
If you don't want the scrollbar at all, you'll have to use lists or divs instead of a table.

The way you have used tr and td tags, the data in table is bound to overflow.
You have to decide how many rows and colmuns your table should have, when you are using simple html table. just put tr and td tags accordingly, and then you are done.http://jsfiddle.net/6REkj/Fiddle

Related

I am not sure if I am writing this CSS correctly.

I wrote in parenthesis and in all caps, the things I am confused about in my homework instructions.
This is my homework instructions:
On the first line of your "main.css" file create a comment that reads "general". Under that comment write the following
Using the universal selector set the margin and padding to zero for all elements. We are doing this to eliminate all the default margin and padding that the browsers add.
Add the css line from the templates page (on the course website) that groups some selectors and sets them all to "display block".
Skip one line and write a comment that reads "wrapper". Under that comment write a css id of "wrapper" and add the following properties.
Give it a width of 1024px
Give it a margin property with the values of 0 and auto (margin: 0 auto centers the page on the browser window. We have to have a width to allow it to show that it is centered.)
Skip one line and write a comment that reads "main".
Put a border of 1px solid #000 around the left, right bottom of the main element.
(NOT SURE IF I DID THIS PORTION CORRECTLY ^)
Add a padding of 10px to the main element. We add a padding so the content will not butt up against the edge of the main element
Using a contextual selector select all the images within the divisional element with the id of "images" and set each image height to 90px, width to 120px and a margin of 20px around the image. We are using CSS to resize our images.
(NOT SURE HOW TO WRITE A CONTEXTUAL SELECTOR TO SELECT ALL THE IMAGES WITH THE DIV ELEMENT WITH THE ID of "images")
This is what I have created but am not sure if it is correct:
/* general */
Using the universal selector set the margin and padding to zero for all elements. We are doing this to eliminate all the default margin and padding that the browsers add.
*{margin: 0; padding: 0;}
article, aside, figure, footer, header, main, menu, nav, section {display: block;}
<style>
/* wrapper */
#wrapper {width: 1024px; margin: 0 auto; }
/* main */
main{border-left: solid 1px #000; border-bottom: solid 1px #000; border-right: solid 1px #000; padding: 10px; }
div images, #images {height: 90px; width: 120px; margin: 20px; }
</style>
The wording in your homework is incredibly poor, but what I believe you're looking for is to target all elements with an ID of images contained within a DIV. This would be:
div #images {
height: 90px;
width: 120px;
margin: 20px;
}
This will target any element with the ID of images inside any DIV, even if there is an element in between them (such as <div><span><img id="images"></span></div>). Note that you can also target direct descendants with >. div > #images will target <div><img id="images"></div>, but not <div><span><img id="images"></span></div>.
Keep in mind that having multiple elements on the page with the same ID is invalid markup, and the page will fail to validate correctly. The only situation where this would be valid is if your teacher is meaning to have a single element called #images on multiple different pages. You should use classes for targeting multiple elements on the same page. It's possible your teacher meant for you to use a class, which would be div .images.
As for your border, you have done it correctly, though note that you can set all four borders at once with the shorthand border:
main {
border: solid 1px #000;
padding: 10px;
}
Also, keep in mind that your second line should also be in a comment, or else it will throw a syntax error:
/*Using the universal selector set the margin and padding to zero for all elements. We are doing this to eliminate all the default margin and padding that the browsers add.*/
Hope this helps! :)
Hi i will try to answer this the best that i can, i am only a programming student so this is my best shot :)
First of all, id's has to be unique you cant have two identical id's on the same page.
If you have etc
<div id="test"></div>
<div id="test"></div>
And you try to style it like #test{background-color: red} only the last div will actually have a red background.
But basically this is what he wants:
/*--GENERAL--*/
*{
margin:0;
padding: 0;
}
/*--WRAPPER--*/
#wrapper{
width: 1024px;
margin: 0 auto;
}
/*--MAIN--*/
main{
border-left: 1px solid #000;
padding: 10px;
}
div #images img{
height: 90px;
width: 120px;
margin: 20px;
}
Examples of contextual selector
I hope this will help you with your programming journey! :)

Fluidly vertically expanding DIV or TEXTAREA

I want a textarea to take up as much vertical space as possible without overlapping any other visual elements. Obviously different screens / devices are different heights so I need the solution to be fluid (I think that's the right term).
The other questions I've looked at don't involve textareas, instead using (child) DIVs whose content is already determined. I don't need the textarea to expand dynamically to fit it's content, I just want it to be as tall as possible but without obscuring any other elements.
I've collected together parts of answers to similar questions but can't quite make it work:
http://jsfiddle.net/wa5zU/
CSS:
body, html {
height:100%
}
p {
text-align:justify
}
textarea {
resize:vertical;
height:auto;
width:100%;
box-sizing:border-box;
-webkit-box-sizing:border-box;
-moz-box-sizing:border-box;
}
.vexpand {
border:1px solid blue
}
.vexpand {
position:absolute;
bottom:0;
width:90%;
height:auto
}
HTML:
<h2>Some content of variable length / height to fill the top portion of the screen</h2>
<p>Either: 1) make the blue-bordered DIV expand fluidly to fill this gap or 2) make the textarea expand to achieve the same effect</p>
<div class="vexpand">
<div>One line of content related to the textarea that must be kept with the textarea</div>
<textarea rows=5 cols=10>I have heard that textareas need valid rows and cols attributes in order to respond correctly to height and width css</textarea>
</div>
This attempt is based on position:absolute and bottom:0 assuming that the DIV can be expanded upwards. I did it this way because the content above the DIV/TEXTAREA is variable so couldn't find an elegant and robust way to measure from the top.
There is a line of content related to the textarea that must be kept with the textarea, hence encapsulating this content and the textarea in a div. Ideally I would prefer that content to stay above the textarea.
Things I've tried / seen in related questions:
position:absolute and conflicting absolute position
setting the height of body and html to 100% so that CSS can perform calculations
using height:auto or height:100% on the wrapper div .vexpand or the textarea
setting the cols and rows attributes on the textarea so that it responds to height and width
Is this what you want to do?
http://jsfiddle.net/wa5zU/2/
body, html {
height:100%;
margin: 0;
padding: 0;
}
p {
text-align:justify
}
*
{
box-sizing:border-box;
-webkit-box-sizing:border-box;
-moz-box-sizing:border-box;
}
textarea {
resize:vertical;
height: calc(100% - 20px) ;
width:100%;
}
.text-content
{
height: 80%;
overflow: auto;
padding: 10px;
}
.editor
{
height: 20%;
overflow: hidden;
padding: 10px;
}

Wrong height of DIV image wrapper with percentage width values

I want to wrap an image into an html DIV and, since I want this to be fully scalable with the size of the window, I want to set the width of the DIV in percentage as follows:
html
<div id="wrapper">
<img src="http://openclipart.org/people/netalloy/rally-car.svg" />
</div>
css
#wrapper {
position: absolute;
width: 50%;
}
#wrapper img {
width: 100%;
}
The image should determine the height of its container. This is because the image width is set to 100% and the image height is calculated accordingly maintaining the correct aspect ratio.
The result is visible on jsfiddle: http://jsfiddle.net/lorenzopolidori/5BN4g/15/
My questions are:
Why do all modern browsers render the wrapper DIV 5px taller than the inner image?
How can I get rid of this 5px gap, while still setting all the sizes in percentage and without using javascript?
Surprisingly, this happens in Chrome (21.0.1180.89), Firefox (15.0.1) and IE8, while IE7 renders it correctly, matching the height of the DIV with the height of the image.
Check this out :
http://jsfiddle.net/5BN4g/29/
It's a line-height issue :-)
You need :
#wrapper {
width: 60%;
background-color: #aaa;
margin: 50px auto;
line-height:0;
}
#wrapper img {
width:100%;
border: 1px dashed red;
box-sizing:border-box;
}
​
I used box-sizing to make sure the width of the image doesn't overflow the container
................
Hi now add vertical-align:top in your img tag throw css
as like this
#wrapper img {
width: 100%;
border: 1px dashed red;
vertical-align:top; // add this line
}
live demo
OK, fiddling about, I found a good possible solution:
#wrapper img {
display: block;
width: 100%;
border: 1px dashed red;
}
Changing from the default inline display to a block display eliminates the line-height problem straight away.
This approach is also semantically correct because in this case what we really want is a single image wrapped in a DIV without any other elements in it, so the concept of line-height needs to be completely wiped off by displaying the image as a block.
It works on all major browsers: http://jsfiddle.net/lorenzopolidori/5Cpf2/3/
I think you shuold set align property to force browser show correctly img tag.
<div id="wrapper">
<img align="center" src="http://openclipart.org/image/800px/svg_to_png/74557/rally-car.png" />
</div>
DEMO
I think is because it doesn't see as a Table
i added the display:table in your code
And it looks fine now, check the link
Example Display Table
Your issue is that an image -- the <img> tag, to be exact -- is an inline element. All you need to do is set display: block on the image and the extra padding goes away. Demo.

css difficulties with 100% height

I'm trying to create a page with a panel on the left side. The panel has a header, a content area and a footer. The main panel wrapper div is supposed to be 100% of the height of the page. The header and footer do not have a specified height because I only want them to be large enough for their text and padding while the center content area I want to be 100% of the container minus whatever the height of the header and footer is. I'm not sure how or if I can do this in css. Anyone know what to do here? Thanks.
The html page & css is here - https://gist.github.com/1641918
You can use display as table to accomplish this. By setting a height of 100% on the content 'row' and then 0% on the others. Tables try and make their rows match as closely as possible the specified heights.
http://jsfiddle.net/PZALU/
html, body { height: 100%; width: 100%; }
div#container { display: table; height: 100%; width: 100%;}
div#container > div { display: table-row; }
div#container > div > div { display: table-cell; border: 1px solid gray; }
div#header { height: 0%; }
div#content {height: 100%; background: lightgray; }
div#footer { height: 0%; }
I have dealt with this on several occasions. It is possible to to with just CSS in one or two specific cases from my experience. Otherwise, you would need to tag team it with Javascript and CSS. Because, in order to set an element to 100% height, its parent element's height must be delared. Depending on how deeply nested the element is and what siblings it may or may not have before it, will determine if its possible to do with CSS alone.
One method of getting a conent container div to be 100% of the height browser's viewport is via the following styles.
html {
height:100%;
}
body {
height:100%;
}
#container {
min-height:100%;
max-height:100%;
}
<html>
<body>
<div id="container">
...
</div>
</body>
</html>
It can easily get tricky depending on the layout.

<input> in <div> takes up extra space on right

I have an input element inside a div element:
...
<div id="calculator-container">
<input type="text" />
</div>
....
In CSS I make the input width 100%:
#calculator-container {
border: 1px solid black;
background-color: lightgrey;
width: 200px;
padding: 10px;
}
#calculator-container input {
width: 100%;
}
I can't figure out why is there less free space on the right side of the input than on the left (please see the screenshot below). Maybe somebody can advise. Thanks.
Pointing out that on jsfiddle it looks fine but if you copy it locally it looks bad in both IE and Firefox. Here is the jsfiddle link just so you can copy the code: jsfiddle just to get the code
It’s because width means the width of the element’s content area. The <input>’s content area is surrounded by its padding and border.
http://jsfiddle.net/3f7RB/
If you set those to 0, the input no longer takes up more space than is available:
input {
width: 100%;
border-style: none;
padding: 0;
}
http://jsfiddle.net/3f7RB/1/
(Of course, form elements are often rendered a bit differently from regular elements, so different browsers may do different things.)
If you want padding on the <input>, you can either declare that as a percentage too:
input {
width: 96%;
border-style: none;
padding: 4px 2%;
}
http://jsfiddle.net/3f7RB/5/
Or use box-sizing (not supported in IE 6 or 7) so that width: 100% applies to the <input>’s content, padding and border combined:
input {
width: 100%;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
http://jsfiddle.net/3f7RB/6/
Because the input element gets width:100% which is 200px. this however doesnt take into account that it has a border of 2px, meaning it actually should be 196px.
try this:
http://jsfiddle.net/QLFrj/
#calculator-container input {
width: 196px;
}
Only problem is that it is no longer a percentage...
the reason why it's to right because of the border because it's to the width of input field means the width of input field is 100% + 2px. So, you can use box-sizing property got this:
Check this
http://jsfiddle.net/3f7RB/4/
OR
you can use outline property also . like this:
Check this
http://jsfiddle.net/3f7RB/7/
I've tried here and it works fine. Maybe another CSS statement is overriding some attributes of your div or input. You may try to inspect the elements with Firebug (on Firefox) or Google Chrome.
This happens because your input element wants to be 200px too. The width: 100% applies to the parent-element. In this case the #calculator-container.

Resources