Aligning a Child Div in a parent div [duplicate] - css

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Make outer div be automaticly the same height as its floating content
I feel like I'm missing something very simple here...
We have a simple setup: a parent div that contains a child div.
I want to:
make the parent resize its height based on the child
align the child to the right edge of the parent instead of the default left.
Using float:right will cause the parent to no longer resize correctly and the child to 'jump out' of the parent.
I've tried using align: right and text-align: right but so far no dice.
HTML:
<div id="parent"> <p>parent</p>
<div class="child"> <p>child</p> </div>
<div class="child right"> <p>child2</p> </div>
</div>
CSS:
div{ padding: 15px; margin: 5px; }
p{ padding: 0; margin: 0; }
#parent{
background-color: orange;
width: 500px;
}
.child{
background-color: grey;
height: 200px;
width: 100px;
}
.right{ float: right; } // note: as the commenters suggested I should also be using a float:left on the other child.
Result:
What I want:
Any suggestions on what I could change either with #parent or .right to make child2 align to the right properly?
EDIT
The best fix I found for this is just using display:table on the parent. Though I haven't tested this in IE it fixes the issue in the browsers I care for and avoids using the un-intuitive overflow:hidden method discussed in the comments.
Even better: set margin-left of the child to auto.

Try floating the contents and adding overflow: hidden to the parent. It's counter-intuitive but worked for me with a similar issue.
EDIT: Also float the first child to the left.

Related

Background of a div inside another one with "white-space: nowrap;" does not cover all the width

Ok, I've got a problem out there. To be short, here's a fiddle. I'll repeat myself here:
HTML:
<div class="container">
<div class="selected">
<span>Why don't you cover all the width!?</span>
</div>
<div>
<span>Little content</span>
</div>
</div>
CSS:
.container {
width: 100px;
white-space: nowrap;
background-color: #0f0;
overflow-x: auto;
height: 200px;
}
.selected {
background-color: #f00;
white-space: nowrap;
}
The first question is: why does not the inner div's background cover the entire span?
The second one: I'd like to have a fix, of course.
And one more thing: the html elements are generated by a third-party tool, to which I have no access, which makes "wrapping it all in another div" thing impossible. Only CSS, only hardcore!
UPDATE:
By the way, the container is itself resizable (a frame inside a frameset to be precise).
EDIT:
I've updated the fiddle in order to provide more info. The problem is, that when the second div will be selected, I'd like the red background to stretch to the width of the longest line.
UPDATE 2:
The above described problem can be solved with display: table-row; (see here). The tricky thing is to make this work even if content is less wide than the container itself (a fiddle).
Divs have width:auto by default. So the inner div is 100px wide, like the outer one. The span overflows out of the div.
In this particular case, the easiest solution is to give the inner div display:inline-block
div div {display:inline-block}
so that it no longer fits itself in its parent, but it moulds itself to the width of its contents.
Updated fiddle.
Edit: to answer your second question: yes, the display:inline-block stops the selected div from being as wide as the container.
Fortunately, that can be corrected by adding
min-width:100%;
in addition to the display:inline-block. See more updated fiddle.
Another edit:
And the question keeps changing. Now it's about frames in a frameset. Oh well.
Here is the latest fiddle that solves the problem as formulated now. But let's see what changes the future has in store...
I think you just need to apply the background color to the span instead of the div.
http://jsfiddle.net/M294p/8/
HTML:
<div class="container">
<div class="selected">
<span>Why don't you cover all the width!?</span>
</div>
<div>
<span>Little content</span>
</div>
</div>
CSS:
.container {
width: 100px;
white-space: nowrap;
background-color: #0f0;
overflow-x: auto;
height: 200px;
}
.selected {
background-color: #f00;
white-space: nowrap;
display:inline-block;
}
The answer to your first question is because you have explicit width to the parent div. You can apply display: inline-block to inner div and remove the width: 100px from the parent.
HTML
<div>
<div class="test">
<span>Why don't you cover all the width!?</span>
</div>
</div>
CSS
.test {
background: red;
display: inline-block;
}
An example : http://jsfiddle.net/M294p/6/

css overflow and margin-left

I have three divs inside a parent div with overflow:hidden; and I want to show the third. So I thought, I could give the first div an margin-left and the two other will be shift to the left.
<div style="width:1000px;background:red;overflow:hidden;height:50px;">
<div style="width:1000px;height:50px;float:left;margin-left:-2000px;">
1
</div>
<div style="width:1000px;height:50px;float:left;">
2
</div>
<div style="width:1000px;height:50px;float:left;">
3
</div>
</div>
But it shows the second div. But if I add margin-left:-1000px; to the second div and replace margin-left:-2000px; to -1000px on the first div it will work correctly. I don´t understand why.
When you set -1000px to div, this div is no longer in relative position, so the another divs assumes relative position from parent.
Fiddle Example for testing:
http://jsfiddle.net/FvBwC/5/
<div class="parent">
<div class="one">1</div>
<div class="two">2</div>
<div class="three">3</div>
</div>
.parent { width:1000px; background:red; overflow:hidden; height:50px; }
.one, .two, .three { width: 1000px; height: 50px; float: left; }
.one { background: blue; margin-left: -1000px; }
.two { background: yellow; margin-left: -1000px; }
.three { background: green; }
But for better solution I'd go with display: none in CSS or .hide() in jQuery.
Because the first div is moved 2000 px left outside the parent element. This basically "removes" it from the relative positioning of everything else inside the parent. In other words, the remaining elements are positioned inside the parent as if the first div was never there. Div 2 is positioned relatively as if it was the first element in the parent, i.e. at left:0. If you want to position div 2 outside the parent, you need to explicitly define its position (like setting its margin:-1000px).
To see whats happening clearer, go to your fiddle and set the 3 child divs to width of 100px, keeping the parent at 1000px. Play with the margins some more. You should see whats happening.
EDIT: If all you are trying to do is show a specific div and hide the other two, just set the other two to display:hide.

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

Set child to content width, ignore parent width, and make parent scroll

With CSS alone, is it possible to obtain the following example, http://jsfiddle.net/LdJ7t/, without explicity knowing the child element's width before hand?
The final result desired:
parent element scrollable to child element
child element's width set to content
#Parent {
width: 100px;
height:200px;
background: #ccc;
overflow:auto;
padding: .5em;
margin: .5em;
}
#Child {
width:300px;
height:100px;
background:yellow;
}​
<div id="Parent">
<div id="Child">
This is a test. This is a test.
</div>
</div>​
It looks like display:inline-block; almost works: http://jsfiddle.net/LdJ7t/1/
I think this is possible. I just can't find a solution.
Your inline-block solution is correct - if you put longer words in or an image, the scrollbar will appear. Text is broken on white space by default.
If you don't want text breaking on white space, you can add white-space: nowrap; to the child div like here: http://jsfiddle.net/LdJ7t/2/

Div element not aligning in the middle of another div element

This is my relevant page markup:
<div id="header">
<div id="logo">
Home
</div>
<div id="user_box">
test
</div>
</div>
And my relevant CSS:
#header {
width: 960px;
height: 110px;
}
#logo {
background: url('/assets/img/logo.png') no-repeat center;
width: 300px;
height: 110px;
float: left;
}
#user_box {
width: 300px;
height: 60px;
float: right;
vertical-align: middle;
}
Now, I want to position the user_box div in the vertical middle of the header div. After a lot of Google'ing and experimenting, I have learned that this isn't easy. Apparently, I can't vertical align a block element such as a div. So I'm looking for a different way to do this.
I saw the hacky display: table; method and tried using it, but it didn't change a thing. Also tried changing the element to an inline element like a span, but that didn't work either. I even tried using margin: auto 0; for some god awful reason, and that also didn't work at all.
So I'm asking for help. How do I vertically align this div inside my header div?
Thanks!
Set the line-height of user_box equal to the height of header
Working demo: http://jsfiddle.net/AlienWebguy/pyppD/
vertical align doesn't work with divs its for aligning elements in tables. In your case you could just use this
#user_box { margin-top:25px; } /*110-60 = 50/2 = 25*/
So I fiddled around with your code a little bit, and here's what I got: http://jsfiddle.net/3k8XE/
As you can see I'm using a table as the header, and applying the same id to each element, except the two inner divs have changed to td's. I've added an inner td to compensate the space between the two divs since they were originally set to float:left/right.
(Of course the borders are just to show what's actually going on here.)

Resources