<body> background-color property doesn't work correctly with HTML5 DOCTYPE [duplicate] - css

This question already has answers here:
Why does height 100% work when DOCTYPE is removed?
(5 answers)
Closed 7 years ago.
So I've got a basic 2-column HTML layout that I've applied some basic CSS to:
html {
background-color: gray;
}
body {
width: 900px;
background-color: white;
margin: 0 auto;
overflow: hidden;
}
.logo, .nav, .contact {
float: left;
width: 248px;
border: 1px black solid;
}
.about, .banner, .content {
float: right;
width: 648px;
border: 1px black solid;
}
The problem is, the when I add the <!DOCTYPE html> declaration to the beginning of my page, the background-color attribute doesn't work for the body tag. I assume this has something to do with it defaulting to quirks mode without the DOCTYPE, but what am I doing wrong that might be invalid CSS? (I've validated with jigsaw and it doesn't show any errors/warnings.)

Because you were missing the DOCTYPE — which really should have been there to begin with — your page was being rendered in quirks mode. In quirks mode, browsers are known to stretch the height of body to 100% of the height of the viewport. In standards mode, which is triggered by having an appropriate DOCTYPE, body behaves like a regular block-level element, being only as tall as its contents by default. In your case, this results in body's background color not being visible.
There's nothing inherently wrong with your CSS, which is why it validates, but if you want body to stretch to the height of the viewport in standards mode, you should add the following height properties to html and body respectively:
html {
height: 100%;
}
body {
min-height: 100%;
}

Related

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

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

height: calc(100%) not working correctly in CSS

I have a div that I want to fill the whole height of the body less a set number in pixels. But I can't get height: calc(100% - 50px) to work.
The reason I want to do this is I have elements that have dynamic heights based on some varying criteria, e.g. height of the header changes based on different elements it can contain. A content div then needs to stretch to fill the rest of the available space available.
The div element, however, stays the height of the content - it doesn't seem as if it interprets 100% to be the height of the body element.
body {
background: blue;
height: 100%;
}
header {
background: red;
height: 20px;
width: 100%;
}
h1 {
font-size: 1.2em;
margin: 0;
padding: 0;
height: 30px;
font-weight: bold;
background: yellow;
}
#theCalcDiv {
background: green;
height: calc(100% - (20px + 30px));
display: block;
}
<header>Some nav stuff here</header>
<h1>This is the heading</h1>
<div id="theCalcDiv">This blocks needs to have a CSS calc() height of 100% - the height of the other elements.</div>
I would appreciate any help or pointers in the right direction.
You need to ensure the html and body are set to 100% and also be sure to add vendor prefixes for calc, so -moz-calc, -webkit-calc.
Following CSS works:
html,body {
background: blue;
height:100%;
padding:0;
margin:0;
}
header {
background: red;
height: 20px;
width:100%
}
h1 {
font-size:1.2em;
margin:0;
padding:0;
height: 30px;
font-weight: bold;
background:yellow
}
#theCalcDiv {
background:green;
height: -moz-calc(100% - (20px + 30px));
height: -webkit-calc(100% - (20px + 30px));
height: calc(100% - (20px + 30px));
display:block
}
I also set your margin/padding to 0 on html and body, otherwise there would be a scrollbar when this is added on.
Here's an updated fiddle
http://jsfiddle.net/UF3mb/10/
Browser support is:
IE9+, Firefox 16+ and with vendor prefix Firefox 4+, Chrome 19+, Safari 6+
I was searching why % doesn't seem to work. So, I tested out using 100vh instead of just setting it at 100% it seems that 100vh works really well across almost all browsers/devices.
example: you want to only display the top div to the user before it scrolls, like a hero banner module. But, at the top of the page is a navbar which is 68px in height. The following doesn't work for me at all doing just %
height: calc(100% - 68px);
There's was no change. The page just stayed the same. However, when swapping this to "vh" instead it works great! The div block you assign it too will stay on the viewer's device hight only. Until they decide to scroll down the page.
height: calc(100vh - 68px);
Change the +/- to include how big your header is on the top.
If your navbar is say 120px in height then change 68px to 120px.
Hope this helps anyone who cannot get this working with using normal height: calc();
First off - check with Firebug(or what ever your preference is) whether the css property is being interpreted by the browser. Sometimes the tool used will give you the problem right there, so no more hunting.
Second off - check compatibility: http://caniuse.com/#feat=calc
And third - I ran into some problems a few hours ago and just resolved it. It's the smallest thing but it kept me busy for 30 minutes.
Here's how my CSS looked
#someElement {
height:calc(100%-100px);
height:-moz-calc(100%-100px);
height:-webkit-calc(100%-100px);
}
Looks right doesn't it?
WRONG
Here's how it should look:
#someElement {
height:calc(100% - 100px);
height:-moz-calc(100% - 100px);
height:-webkit-calc(100% - 100px);
}
Looks the same right?
Notice the spaces!!!
Checked android browser, Firefox for android, Chrome for android, Chrome and Firefox for Windows and Internet Explorer 11. All of them ignored the CSS if there were no spaces.
Hope this helps someone.
try setting both html and body to height 100%;
html, body {background: blue; height:100%;}
All the parent elements in the hierarchy should have height 100%. Just give max-height:100% to the element and max-height:calc(100% - 90px) to the immediate parent element.
It worked for me on IE also.
html,
body {
height: 100%
}
parent-element {
max-height: calc(100% - 90px);
}
element {
height:100%;
}
The Rendering in IE fails due to failure of Calc when the window is resized or data loaded in DOM. But this method mentioned above worked for me even in IE.
You don't need to calculate anything, and probably shouldn't:
<!DOCTYPE html>
<head>
<style type="text/css">
body {background: blue; height:100%;}
header {background: red; height: 20px; width:100%}
h1 {font-size:1.2em; margin:0; padding:0;
height: 30px; font-weight: bold; background:yellow}
.theCalcDiv {background-color:green; padding-bottom: 100%}
</style>
</head>
<body>
<header>Some nav stuff here</header>
<h1>This is the heading</h1>
<div class="theCalcDiv">This blocks needs to have a CSS calc() height of 100% - the height of the other elements.
</div>
I stuck it all together for brevity.
If you are styling calc in a GWT project, its parser might not parse calc for you as it did not for me... the solution is to wrap it in a css literal like this:
height: literal("-moz-calc(100% - (20px + 30px))");
height: literal("-webkit-calc(100% - (20px + 30px))");
height: literal("calc(100% - (20px + 30px))");

CSS Print Stylesheet: hide everything except specific image, show that full-page

I'm trying to build a stylesheet that prints only a specific image, and sizes the image to cover the entire page.
In my media="print" stylesheet, I have:
#page {
margin: 0.5in;
}
body {
width: 100%;
}
body * {
visibility: hidden;
}
#specificimage {
visibility: visible;
position: fixed;
top: .5in;
left: .5in;
width: 7.5in;
height: auto;
}
The html structure is similar to this:
<body>
<div>
<div>
<div>
<img id="specificimage" src="image.png" />
</div>
</div>
</div>
</body>
It prints fine in Firefox 19, but that is the only browser I've tested that works correctly. IE 9 doesn't show anything; Safari 5.1.7 (PC) shows only a sliver of the image on the left side of the page; Chrome 25 shows the full image, but in a small portion of the page.
Anyone know of anything else I can try?
As Diodeus notes in the comments, the visibility of any given element doesn't matter if its parent is not displaying — in fact in many browsers the resource won't even be loaded.
I would propose these changes:
* {
background: none !important;
direction: ltr !important;
display: none !important;
font-size: 0 !important;
height: 0 !important;
line-height:-9999 !important;
margin: 0 !important;
padding: 0 !important;
position: static !important;
text-indent:-9999em !important;
width: 0 !important;
white-space:normal !important;
}
html, body, div, #specificimage {
display: block !important;
}
#specificimage {
left: 0 !important;
position: fixed !important;
top: 0 !important;
width: 100% !important;
}
The * rule is pretty heavy, but makes sure that:
The size (or number of pages, because of a page structure taller than one page) will not be influenced by metrics, which is influenced by border, height, margin, width;
Text immediately inside a div is not visible: negative text indent, forced direction of left to right, plus zero font-size and forced wrapping via white-space: normal mean it will be hidden out to the left and won't extend the width. a negative line-height means it will be hidden off to the top too, and won't extend the height (or number of pages) if it's extremely long.
Position: static means left, right, top or bottom won't extend the page canvas more than it needs.
The important rule is there because whatever rules giving any of these properties to your elements in the first place will always be stronger. Without making assumptions about the document structure, we have to apply this override. If you need to make this trump more specific class and selector-based rules with !important specified, you can append :nth-child(n) to the asterisk any number of times, but this won't help against inline styles or rules with ID selectors that also have importance toggled.

height percentage problem for body tag - unresolved through searches

I have read a vast amount of posts on the subject of css heights filling the viewport and have failed to find a working answer. So I'm reluctantly starting yet another thread about this in the hope of finding the missing part of the jigsaw I have probably been staring at without seeing it.
My DOCTYPE is xhtml transitional and I'm currently testing on IE6, FF6 and Safari 5 with the same problem.
I have a container div that also displays an image driven border within a table and I want this to fill the browser window, no bigger, no smaller but adaptable to each browser (minimum heights will be set to ensure all content is contained to account for older resolutions).
I have set the html and body styles as follows:-
html {
height:auto !important;
height: 100%;
min-height: 100%;
border: solid;
border-color: black;
overflow: hidden;
}
body {
height: 100%;
height:auto !important;
min-height: 100%;
border: solid;
border-color: black;
}
As you can see I have added a border to each of the elements so that I can actually see the size of each when I view the page. The html element fills the window fine, but the body element doesn't. It just shows a short box along the top of the window.
Can anyone offer a suggestion as to what may be causing the problem?
This is all you need for the css:
html,body {
padding: 0;
margin: 0;
height: 100%;
}
Live example: http://jsfiddle.net/tw16/gyAKJ/

Define an <img>'s src attribute in CSS [duplicate]

This question already has answers here:
Is it possible to set the equivalent of a src attribute of an img tag in CSS?
(24 answers)
Closed 7 years ago.
I need to define an <img>'s src attribute in CSS. Is there a way to specify this attribute?
just this as img tag is a content element
img {
content:url(http://example.com/image.png);
}
#divID {
background-image: url("http://imageurlhere.com");
background-repeat: no-repeat;
width: auto; /*or your image's width*/
height: auto; /*or your image's height*/
margin: 0;
padding: 0;
}
No there isn't. You can specify a background image but that's not the same thing.
CSS is not used to define values to DOM element attributes, javascript would be more suitable for this.
No. The closest you can get is setting a background image:
<div id="myimage"></div>
#myimage {
width: 20px;
height: 20px;
background: white url(myimage.gif) no-repeat;
}
After trying these solutions I still wasn't satisfied but I found a solution in this article and it works in Chrome, Firefox, Opera, Safari, IE8+
#divId {
display: block;
-moz-box-sizing: border-box;
box-sizing: border-box;
background: url(http://notrealdomain2.com/newbanner.png) no-repeat;
width: 180px; /* Width of new image */
height: 236px; /* Height of new image */
padding-left: 180px; /* Equal to width of new image */
}
They are right. IMG is a content element and CSS is about design.
But, how about when you use some content elements or properties for design purposes?
I have IMG across my web pages that must change if i change the style (the CSS).
Well this is a solution for defining IMG presentation (no really the image) in CSS style.
1: create a 1x1 transparent gif or png.
2: Assign propery "src" of IMG to that image.
3: Define final presentation with "background-image" in the CSS style.
It works like a charm :)

Resources