So i have:
<body style="border:1px solid red;width:100%;">
<div style="position:absolute;left:2000px;">
1
</div>
<body>
Is there any way to make body width to be 100% of document (including "scrolling space") instead of 100% of inner window width in this case?
I mean i need the result as if i applied "width:2000px;" to the body, but without knowing this number.
I know, that it will take one line of code in js and still i wonder, if i can do this with pure css.
To clarify:
When i write "width:100%;" i expect, that body width will stretch up to 2000px (to include that absolutely positioned div), but it stretches only to 1024px (browser window width).
There is a logical puzzle with this layout.
<body style="background:red;width:100%;">
<div style="position:absolute;left:2000px;">
1
</div>
<body>
Because the inner div is positioned absolutely, it is out of the document flow, and therefore, the parent block container, <body>, cannot compute a width based on the absolutely positioned child element.
By assigning a percentage width of 100% to <body>, the width is actually being computed based on the width of the root element, in this case, <html>, which may in turn, inherit its height from the viewport.
This effect cannot be achieved by CSS alone.
If you need the inner div to be absolutely positioned, then you will need some JavaScript/jQuery functionality to determine the width of <body> based on some custom rules that you want to specify.
The problem is position: absolute what you can do is wrapping your div inside another one like this:
<body style="border:1px solid red;width:100%;">
<div style="width:2000px;">
<div style="position:absolute;left:2000px;">
1
</div>
</div>
<body>
because when you make any element absolute is not belongs to is parent anymore and it becomes separate element in document (in document flow). If this answer is not what you want, tell me what you want exactly to do (what is your design decision) then I can give you alternative designs to solve your problem.
The width property doesn't have anything to do with the objects' child elements. Additionally, by absolute positioning that element, it actually causes the parent to COMPLETELY ignore any size parameters of that particular child element. But even with a relatively positioned object with an offset, only the initial position of the element would have an impact on its parent and not the offset location of it.
Setting width to 100% will cause it to fill 100% of its parent container, in this case the <html> element. And by explicitly stating a width, even if you had a large amount of unwrapped content inside that container, your width would actually be locked at 100% (or the width of the browser window) regardless of said child content.
You could TRY and set the width to 200%, which would cause it stretch to the right beyond its parent container. But this width would not be driven by the absolute positioned child element, and may not be responsive enough for your needs.
As was already stated above, there is no pure CSS solution for what you're trying to do and you'll need to use at least some javascript to accomplish what it sounds like you're trying to accomplish.
Related
At the moment I have a large <div> that I'd like to add a bottom margin to, to push it up from the bottom of the page. However this currently has no effect because its parent, the <body> tag, is smaller than it, as you can see here:
The body tag is highlighted in blue and brown, but you can see my div (the white border) extending below it.
However if I apply the trick of setting the <body> and <html> tags to height: auto and min-height:100% to make sure they fill the entire page, all of my inner content loses its size, because they all use percentage heights and no longer have a parent with a fixed height.
How can you use percentage heights if the parent tag has a height of auto?
I'm afraid you can't do this. A percentage height on an element only works if the parent element has a specific height. See also: CSS – why doesn’t percentage height work?
Without fixing the widths of any of the elements, I would like the parent div element to ignore the text when setting it's width. I want the element's width only to be affected by the width of the image.
<div>
<img src="https://lh4.ggpht.com/9BAW9uE48gxNUmnQ7T6ALpNTsrCHOZBMfF__mbamBC36edSw0uc-kjQxgtZ3O3aQWFY=h900"/>
<p>I want this text to wrap once this paragraph element reaches the width of the image.</p>
</div>
div {
background: green;
display: inline-block;
}
my jsFiddle
Any advice is greatly appreciated
Change display property of div to table-caption
(Tested in firefox and chrome)
Updated jsfiddle
Here's the best that I've found:
http://jsfiddle.net/y8Qnd/3/
What I've done is to take the p tag out of flow with position: absolute so that the containing div has the width of just the image. Then, have the p tag inherit the width of its parent, the container. This does not fix the width of the p tag, and is completely cross browser.
This would mean you would have to move up the DOM tree, as you want the image to determine it's parent width. Moving up the DOM tree is unfortunately not possible (yet).
As an alternative, you could position the text absolute, to lift it out of the document flow, and therefore not influence the width of it's parent div. This however would also mean that the height does not get influenced, which is probably not what you are after. You could mimic the correct height by repeating the parent background, but the content underneath would not get pushed down, so that is also not really an option I think. I set up an example anyway: http://jsfiddle.net/y8Qnd/2/
The only option I can think of is javascript. Get the width of the image and apply it to the parent container. In jQuery (I will probably get bashed for using jQuery for such a trivial thing, but I am just not used to writing 'old school javascript' anymore...) it would look something like this:
var $wrapper = $('div'); // you will probabaly want to use some id or class here
var width = $wrapper.find('img').width();
$wrapper.css('width', width);
and an example: http://jsfiddle.net/y8Qnd/6/
I have a bunch of html that is absolutely positioned and then html snippet that is supposed to show after that. But they over lap.
http://jsbin.com/okamot/1/edit
Everything under .drag-drop is supposed to be absolutely placed so the height and width of .drag-drop become zero. The exhibit button and the exhibit text are supposed to show after the bolded This is Drag and Drop Item. But because the height of .drag-drop is zero it shows right over the contents of .drag-drop`.
I have had this issue before, but fortunately it was easy to calculate the height of the children of .drag-drop and then I would set the height of the .drag-drop to be that using javascript. This time it is harder as it contains more children and they are not constant. How would I change my css so that the Exhibit shows below the drag drop ?
Absolute positioning removes the element from the layout, therefore the children are no longer part of the calculation of the parent's sizing. You'll need to use JS to solve this.
The best way is not to make the content absolute positioned at all. Could you make them relative positioned, or float them? You can still manipulate their position, height, width, etc., and they'd have layout so the containing div would have the correct height.
Note if you float them, you may need to add a "float breaker" at the bottom of the containing div to get it to calculate the height correctly:
....
<div>some floated content</div>
<br style="float: none;"/> // float-breaker right before containing div closes
</div>
Otherwise the previous answerer is correct, you'll need some js hackery.
I have a div C which height is set up using max-height. This div contains a div D.
I want the contained div D to have the exact same height (and not more) than the containing div C.
If I use the height property for div C, like here
the height of the div C is set up using height: 90%
the height of div D is set up using height: 100%
Then, Everything works fine, and the height of div D equals the
height of div C
If I use the max-height property for div C, like here
the height of the div C is set up using max-height: 90%
the height of div D is set up using height: 100%
Then, the height of div D is not equals to the height of div C (a lot
bigger since the content inside it is very long). In the fiddle, it looks good, but if you inspect div D, you will see it's a lot bigger.
But I need to use the max-height css property, how can I set up the height of div D to be equals to the one of div C only with css?
<div id="container">
<div id="A">
<div id="B">
<div id="C">
<div id="D">
<div id="D1">D1</div>
<div id="D2">
D2 - very long content
</div>
</div>
</div>
</div>
</div>
</div>
Thanks!!!
The reason why things do not work the way you expect is simply because max-height does not set the height of the containing div. All it does is, as its name implies, set a maximum limit to the height of the div.
Here's a quote from the W3 CSS2 specification on how the percentage heights are calculated on block elements. This might help to shed some light on the matter:
The percentage is calculated with respect to the height of the generated box's containing block. If the height of the containing block is not specified explicitly (i.e., it depends on content height), and this element is not absolutely positioned, the value computes to 'auto'.
In your case the height of the containing div is not set explicitly and depends on content height, because when you set the max-height of the containing div to 90%, and there is not enough content to stretch the containing div to 90% of the height of its own containing element, the height of the containing div will be less than 90% of the height of its own containing element.
An attempt to explain what I believe is happening
The browser renders the containing div with an initial height of auto, which computes to 0px as there is no content yet. Along comes the contained div which wants to be rendered with a height of 100% of the height of its containing block, the browser realizes that this is ridiculous, as 100% of 0px is exactly 0px again. So it decides to set the height of the contained div to auto instead. If it didn't do so, then the contained div would never be visible, because no matter what happens next, 100% of the containing block's height of 0px is always going to be 0px. Remember that the browser is trying to stick to this part of the rule quoted above:
The percentage is calculated with respect to the height of the generated box's containing block
ONLY NOW along come some more div's which would like to be rendered inside the contained div. At the moment when the previous decisions were made, the browser didn't yet know about these div's, they're a bit late to the party. If the browser was then to backtrack and fix itself up after it had rendered those div's, it would effectively be breaking the part of the rule quoted above. As it would indirectly* be setting the percentage height of the contained div based on the height of its contents.
Because of this the W3 specification people have come up with the second part of the rule. Which lets the browser decide to set the height of the contained div to auto if the height of its containing div is not set (and therefore defaults to auto).
So you could say that those late div's are lucky that the browser has taken some precautions and is still able to render those div's, as it has been preemptive and has set the height of the contained div to auto to accommodate for latecomers.
*by calculating the height of the containing div based on the height of the contents of the contained div, and then basing the percentage height of the contained div on this value.
In conclusion
Browsers are just sticking to the W3 specification, which is a good thing. Your first fiddle works because the browser makers are adhering to the specification, and your second fiddle doesn't work for the exact same reason.
The solution
You can only fix your issue by making sure that the div which you want to have a height of 90% of the browser window is a direct descendant of a div which has its height set to 100% of the browser window. If the ancestor div is not absolutely placed, every ancestor of the div, all the way up to the html document element, would also have to have a height of 100% set on itself.
The line above is true, except if an ancestor is encountered which is absolutely placed (which would take it out of the regular document flow), without this ancestor itself having an ancestor with position: relative set (which would force its absolute positioning to be based on the position of its relatively positioned parent instead of on the height of the browser window), and this ancestor is set to be the height of the browser window (using top: 0px; bottom: 0px;). In that case the running up the DOM tree will stop at the absolutely positioned ancestor.
it's because D is inside of C wouldn't just saying
#D {height: 100%;}
work because that would be telling it to take up 100% of the div it is inside of?
additionally this might help http://css-tricks.com/the-css-box-model/
Take this trivial example and open it:
<html>
<body style="background-image:url(http://upload.wikimedia.org/wikipedia/commons/2/21/Mandel_zoom_00_mandelbrot_set.jpg);background-repeat: no-repeat; background-position: top center;">
<div style="width: 8000px; border: 3px solid red;">Demo</div>
</body>
</html>
The page is made so that the body has a top-centered background picture and a containing element which overflows window boundaries so there is horizontal scrolling (if you have a monitor wider than 8000px then you're really cool, please make the window smaller and refresh).
The problem is that for some reason the <body> doesn't stretch to contain the <div>. It just stays the same width as the viewport and the <div> overflows it. This in turn causes the background to be centered at the wrong place and crops it to the size of the viewport. Quite ugly when you scroll to the right.
I've already found a solution to this problem, but I'm wondering WHY this is so? It seems to be consistent across browsers too. But in my opinion this is quite counter-intuitive and basically plain wrong. The container element should be big enough to contain it's children - unless they are absolutely positioned of course in which case they don't participate in the layout calculations.
Blocks simply do not stretch horizontally to accomodate their child content, at all; never have.(1) That's something that only happens in the vertical axis.(2) Logically, both dimensions can't be stretchy; one has to be fixed (wrt parent). In CSS, the width of a block element in normal flow is derived solely from the parent (minus paddings, margins, borders), and then the height follows on from that, seeing how much content you can fit in the block's width and flowing it.
The background image can appear in a confusing place that misleads you to what is actually happening because of this quirk of CSS:
For documents whose root element is an HTML "HTML" element or an XHTML "html" element that has computed values of 'transparent' for 'background-color' and 'none' for 'background-image', user agents must instead use the computed value of the background properties from that element's first HTML "BODY" element or XHTML "body" element child when painting backgrounds for the canvas, and must not paint a background for that child element. Such backgrounds must also be anchored at the same point as they would be if they were painted only for the root element.
This is a nasty hack put in place because people were used to putting backgrounds on ‘body’ and having it fill the viewport, even though the <body> element itself does not represent the viewport.
(1) except in a few special cases, like float and position: absolute elements without a declared width.
(2) unless you deliberately stop that by setting height/overflow.
The exception to expanding is the viewport. Nothing expands the viewport unless its direct or attached contents require it -- this includes that div and table elements (eg, display: table-cell on body) -- but not a block container.