Parent-child height problem - css

I have a parent div that has position: relative and his child has position: absolute. Such positions is a must. The problem is the parent does not stretch to the height of the child. The question is how to make it stretch to the height of the child?
The mark-up is similar to this:
<!DOCTYPE HTML>
<html>
<head>
<style>
.parent {
position: relative;
border: solid 1px red;
}
.child {
position: absolute;
border: solid 1px red;
}
</style>
</head>
<body>
<div class="parent">
<div class="child">Hello World!</div>
</div>
</body>
</html>

Add overflow:hidden to your parent.
Edit: My mistake, this will only work if the children are floating. This cannot be achieved if the child is position absolutely. When you absolutely position an element, you're taking it out of the document flow. As far as positioning is concerned, that element is no longer a "child", even though semantically it still is.

give a height:100% to both the child and the parent.

Unfortunately, I don't think there's a way to do it, without using Javascript.
edit: Perhaps if you show why they need to be position:relative and position:absolute, we can come up with a way to remove that restriction so that what you want is possible.

Related

`absolute` child does not relate to `relative` parent when parent is `table-cell` - only firefox

Situation
html:
<div class="container">
<div class="parent">
<div class="child">x</div>
</div>
</div>
css:
.container {
display: table;
}
.parent {
display: table-cell;
position: relative;
}
.child {
position: absolute;
right: 0;
}
What I expect:
the .child should be positioned to the right edge of .parent. Works in Chrome.
What I get in Firefox:
the .child is positioned to the right edge of the closest "non static" parent which is has not display: table-cell.
Fiddle
http://jsfiddle.net/SYG5k/2
Question
Why does display: table-cell influence the positioning of child elements, or, why is position: relative ignored on table-cell elements? Can I work around this if I rely on table-cell?
You need to put position: relative; in your parent.
So in the code in your question add position: relative; to .container
Or in your jsfiddle add position: relative; to .parent
.parent {
height: 150px;
width: 450px;
display: table;
margin-top: 400px;
background: #bbb;
position:relative;
}
Related : Firefox ignores absolute positioning in table cells and Positioning context on table-cell element in Firefox
About your questioning 'why' : It's no more a 'block' level element. It's a table-cell so positioning will behave in a different way (in this case, with firefox).
See this to understand deeper about 'tables' behaviors
http://jsfiddle.net/SYG5k/12
Add a wrapper to your absolute element and make it relative, so you will have something like table-cell > relative wrapper > absolute element
http://jsfiddle.net/SYG5k/13/
<div class="rel">
a
<div class="absolute">x</div>
</div>
.foo, .rel {
position: relative;
}
This is a work around I can't explain why it doesn't work normally. Perhaps someone else will answer that for you
Edit : my mistake the wrapper is supposed to wrap everything in the cell, it's what I originally wanted to code, more of a typo. I updated the fiddle above
A work around may be to use an inner div with a width and height of 100%, and set that to position:relative;
HTML:
<div class="parent">
<div class="cell foo">
<div class="cellInner">
a
<div class="absolute">x</div>
</div>
</div>
CSS:
.cellInner{
position:relative;
width:100%;
height:100%;
}
Updated JS Fiddle: http://jsfiddle.net/SYG5k/11/
I was adding a popup menu that appears on each row of the table as the user mouses over it when I ran into this FF problem. Based on the very useful info above, I ended up putting a div wrapper inside the table cell in each row where I wanted my absolutely positioned popover menu to located, and set its display property to relative. My JS then adds the absolutely position menu inside the div as each row is rolled - it has to be a child of the the relatively positioned div, of course. Note that the div will shrink-wrap the td's content rather than filling the td as I expected, but no matter, you then have a relative context, and you can use top and left on the absolutely positioned child element to locate it exactly where you want it with respect to the table cell.

A CSS absolute positioning mystery

Consider the webpage below. The <img> is positioned absolutely relative to its parent, and when I load this page on Safari or Firefox, the <img> appears in the top-right, as expected (see first image). However, when the border is removed from from the <div>, for example, by setting border-width: 0, the <img> positions itself absolutely relative to the <p> tag, its sibling! See picture #2. Why is this? What difference should the border make?
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<style type="text/css">
body {
margin: 0;
}
div {
position: relative;
left: 0;
top: 0;
border: 1px solid red;
}
img {
position: absolute;
right: 0;
top: 0;
}
p {
margin: 20px;
}
</style>
</head>
<body>
<div>
<img src="content/en/flag.png" />
<p>This is a test</p>
</div>
</body>
</html>
Your image is always at the top-right. It has to do with collapsing margins.
Try to do it with a background color. You will see that your div is moving away from the top of the body a few pixels. If you delete p's margin everything would be fine, or setting p as an inline element or floating it, or even setting an overflow to auto, hidden or scroll to the parent. Another way to fight the collapsed margin is to add a border to the container element. So you really was solving this with that border.
But image is always where it is supposed to be.
Its really strange indeed but let me try to explain this actually the elements are not float and you are using margin on p tag which the div is taking properly when it has border and failed to implement it when its removed if add float property than the div will also gain its height
add overflow:auto; to div it will fix the problem

absolute position affects width?

I am new to css. I am wondering why when I change the positioning of the div element to absolute, the width of the div element changes? Tried it out in Chrome v25.0.1364.172m and IE9, both have the same outcome.
Simple example:
<!doctype html/>
<html>
<head>
<title>test</title>
<style>
div {
position:relative;
border-width: 1px;
border-style: solid;
border-color: black;
}
</style>
</head>
<body>
<div>test</div>
</body>
</html>
Because absolutely positioned elements do not behave as block level
elements and do not flow after each other like normal a<div>does.
You will need to set a width and a height for a div that is absolutely positioned, depending what it contains.
Your absolutely positioned element will position relative to the first parent element it is in. So, a simple example:
A simple 'gotcha' is not setting the parent element to have position: relative;
<!-- I'm a parent element -->
<div style="width: 500px; height: 500px; position: relative; border: 1px solid blue;">
<!-- I'm a child of the above parent element -->
<div style="width: 150px; height: 150px; position: absolute; left: 10px; top: 10px; border: 1px solid red;">
I'm positioned absolutely to my parent.
</div>
</div>
Like SMacFadyen said, the most likely cause is missing position relative in the container.
However, if the container is in position relative and has a small width and the inner content in absolute, when you position the inner content using left or right its content might break into multiple lines. In this scenario you will want to change the white-space property to nowrap or some other option that better suits your needs.
Because the element, which you give absolute position take the width from his parent and didn't behave as a block element.

trying to vertically align div inside div

i am trying to vertically align a div inside another div at the bottom and i do not want to use relative/absolute positioning. below is my markup. it seems to work. but i am not sure whether this is the best solution. can anyone recommend a better way? also, in FF if i remove the border around the container, it stops working. does anyone know why?
thanks
konstantin
<html>
<head>
<style type="text/css">
.container
{
background-color: #ffff00;
height: 100px;
line-height: 100px;
border: solid 1px #666666;
}
.container .content
{
margin-top: 60px;
background-color: #ffbbbb;
height: 40px;
line-height: 40px;
}
</style>
</head>
<body>
<div class="container">
<div class="content">test</div>
</div>
</body>
</html>
Do use absolute positioning. I think it is probable that the reason you do not want to use absolute positioning is based on a misconception. Namely, if the container has the position attribute as well, absolute positioning will not be in regard to the whole page, but in regard to the container, and then you will get what you want with:
.container
{
position: relative;
}
.container .content
{
position: absolute;
bottom: 0px;
}
Now, no matter the sizes, your content will be will be at the bottom of the container.
That will work... only thing is you won't be able to put anything in the empty top 60 pixels.
I believe that if you're looking for the best solution, you should indeed use relative/absolute positioning.
Is there any specific reason that you're trying to avoid relative/absolute positioning?

Bottom text align or menu

I have a menu the have rectangular boxes 90x50. Some have single line text, other have multiline text
question : How to VERTICALLY align it to the bottom with pure css no hack please
Vertical aligninment in CSS isn't that easy as you'd intuitively expect. As far the straightforward property vertical-align: bottom works in table cells only. Here's an excellent resource which explains how (not) to vertical align in CSS: Understanding vertical-align, or "How (Not) To Vertically Center Content".
In a nut: the following works in real webbrowsers:
display: table-cell;
vertical-align: bottom;
But thus not in MSIE. You'd like to make the parent element relative and wrap the text in an absolutely positioned element and then put it to bottom. Here's a copy'n'paste'n'runnable example.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Test</title>
<style>
li {
position: relative;
width: 90px;
height: 50px;
border: 1px solid black;
}
li span {
position: absolute;
bottom: 0;
}
</style>
</head>
<body>
<ul>
<li><span>text</span></li>
<li><span>text<br>multiline</span></li>
<li><span>text</span></li>
</ul>
</body>
</html>
I think the vertical-align property does what you want. Otherwise, perhaps you can clarify your problem further?
Edit: You can force table-cell-like behaviour for any other element by using the display property with the value 'table-cell'. I am not perfectly sure if this works with well with the vertical-align property, but perhaps you can build on it. If I remember correctly, an additional intermediate element was required.

Resources