Center aligning child divs and deal with float and fill - css

Consider the following: http://jsfiddle.net/Yq39W/1/
HTML:
<div class="parent">
<div class="child1">
Some text...
</div><div class="child2">
2
</div><div class="child3">
<form>
<input type="text" />
<input type="text" />
</form>
</div>
</div>
CSS:
.parent {
width:100%;
background:red;
margin:0px;
padding:0px;
}
.child1, .child2, .child3 {
display:inline-block;
border:1px solid black;
padding:10px;
}
.child1 {
background:blue;
float:left;
}
.child2 {
height:200px;
background:yellow;
}
.child3 {
background:green;
float:right;
}
How can I vertically center align the child divs, while child2 fills out the remaining space? (Meaning that the child1 and child3 will be moved down a little bit, so that the centers is aligned with center of child2)
What if height is NOT defined explicitly for any of the divs (in the example, child2 is explicitly set to 200px)? Is is still possible to align on the vertical axis?
It is important for me, that no dimensions are defined explicitly (except for parent width which would be 100% and any padding/margin on the elements).
Hope you guys can help out! :)

Assuming you mean vertical centering the child elements with child 2, then remove the floats and just add vertical-align: middle; since they are already display: inline-block. No need to declare a specific height, they'll all be vertically aligned with each other no matter what the tallest element is.
In the demo, I use <br />s to make child 2 taller without an explicit height set just to demonstrate.
Demo: http://jsfiddle.net/shshaw/jnE89/
You may want to set max-width: 33% for the children so that they won't go to multiple lines, but that just depends on the effect you're going for.
Bonus: If you want, you can use text-align: justify on the parent to ensure that your boxes cover the available space, like a grid (see Text-align: Justify and RWD or the updated demo; note that the boxes must have spaces inbetween them in the HTML for it to work)

Related

How can I adjust the width of a nested div to equal the width of an ancestor div?

My pages are structured as nested divs. They have padding and margin so inner divs are typically physically smaller than outer divs. However, in some cases I would like one of the inner divs (red box in the image below) to expand widthwise to match the left and right edges of the outermost div.
<div id="div-a">
<div id="div-b">
<div id="div-c">
<div id="div-d">
</div>
</div>
</div>
</div>
This is just an example -- the number of nested divs can vary. The width of the outermost div is variable. The heights of all the divs are also variable.
I have tried using absolute positioning, but this removes div-d from the document flow. Since I don't know the height of its content, I can't compensate. Any other suggestions? Thank you for any help.
#div-a {
position:relative;
}
#div-d {
position:absolute;
left:0;
right:0;
}
Could this approach be a solution?
#div-c {
position:relative;
}
#div-d {
position:absolute;
padding:0 -(div-c + div-b + div-a padding values) 0 -(div-c + div-b + div-a padding
values)}
#div-c {
display: flex;
align-items: center;
}
#div-d {
width: calc(100% + PADDINGS + BORDERS);
}
PADDINGS: sum of each parents divs padding.
BORDERS: sum of each parents borders.
Unfortunately I could not find a CSS-only solution for my particular problem. I had to resort to Javascript.
wrap the div that needs to be full-width with another div
<div id="div-a">
<div id="div-b">
<div id="div-c">
<div id="div-d-wrapper">
<div id="div-d">
</div>
</div>
</div>
</div>
</div>
use this CSS
#div-a {
position:relative;
}
#div-d {
position:absolute;
left:0;
right:0;
}
apply the following Javascript (using jQuery)
$('#div-d-wrapper').height($('#div-d').outerHeight());
div{
padding:10px;
border: 1px solid red;
}
#div-d{
margin-left:-32px;
margin-right:-32px;
}
i used hard code values to for the given div . My solution is to use Negative margins in css. When the div grows dynamically, you use javascript or jquery to find parent reach from child div and calculate the margins accordingly.
fiddle demo: https://jsfiddle.net/bqrxtLvd/
Source:
Negative margin css tricks
Detailed negative margin

Floated DIV width = 100% - widths of two other floated divs

OK, so here is my problem,
I need to have four DIVs in one line. The First three are float:left and the fourth one is float:right. The container has a specified width.
I need the third div to fill all the space from the second div that is floated to the left, to the fourth div that is floated right.
EDIT: DIVs #1, #2 and #4 have dynamic width as well... They have a certain padding and the content defines the width.
Why not turn the question on its head, and establish how to create the layout you want- in which case, likely the simplest approach would be:
Demo Fiddle
HTML
<div class='table'>
<div class='cell'>fit</div>
<div class='cell'>fit</div>
<div class='cell'>expand</div>
<div class='cell'>fit</div>
</div>
CSS
.table {
display:table;
width:100%; /* <-- will make the divs align across the full browser width */
height:50px;
}
.cell {
display:table-cell;
border:1px solid red;
width:1%; /* <-- will make 1, 2, 4 only fit their content */
}
.cell:nth-child(3) {
width:100%; /* <-- will make 3 expand to the remaining space */
}
Solution Using Floated Elements
Here is one way of doing this using floats.
Arrange your HTML as follows:
<div class="panel-container">
<div class="panel p1">Panel 1 - and a word</div>
<div class="panel p2">Panel 2 - Done. </div>
<div class="panel p4">Panel 4 - End!</div>
<div class="panel p3">Panel 3</div>
</div>
and apply the following CSS:
.panel-container {
width: 600px;
border: 1px dotted blue;
overflow: auto;
}
.panel {
background-color: lightgray;
padding: 5px;
}
.p1 {
float: left;
}
.p2 {
float: left;
}
.p3 {
background-color: tan;
overflow: auto;
}
.p4 {
float: right;
}
The trick is to place the floated elements (.p1, .p2. .p4) ahead of the in-flow content (.p3).
Use overflow: auto on the parent container to keep the floated child elements from affecting the layout outside of the parent element.
I added overflow: auto on .p3 so that the padding gets included within the containing block.
See fiddle at: http://jsfiddle.net/audetwebdesign/9G8rT/
Comments
The one disadvantage of this approach is that the order of the content is altered, that is, .p3 appears after .p4 in the code order.
Another side effect, which may be desirable in a responsive design, is that the child elements will wrap onto 2 or more lines as the parent container width gets smaller.
If you need to retain the content order in the HTML code, the CSS table-cell solution is a good alterantive.
The table-cell solution will keep the child elements on a single line regardless of the width of the parent container.
One final advangtage of the floated element solution is that it is more backward compatible than a CSS table-cell solution, but as we move forward, this is becoming less
of a compelling argument.

Vertical-align middle with display table-cell not working on images

I'm trying to use the vertical-align: middle on a layout to vertically center sometimes text, sometimes images, but it's only working on text. Can anyone tell me why?
HTML:
<div>
<img src="http://jsfiddle.net/img/logo.png"/>
</div>
<div>
<span> text </span>
</div>
CSS:
div{
width:200px;
height:200px;
background-color:red;
display:table;
margin:10px;
}
img, span{
display:table-cell;
vertical-align:middle;
}
http://jsfiddle.net/9uD8M/ I created a fiddle aswell
Put border: 1px solid black on your img, span tags, then inspect both elements in the browser dev. console. You'll notice that the span defaults to 100% height of its parent, while the image has a defined height (the height of the actual image).
So you're not really vertically aligning those elements relative to the div, you're just vertically aligning the text inside the span element relative to the span :)
If you really want to use tables for vertical-centering, here's the correct code:
http://jsfiddle.net/WXLsY/
(vertical-align and display:table-cell go on the parent, and you need wrapper table on them)
But there are other ways to do this (SO has many answers to this question, just use search)
Here is one way of fixing the problem:
HTML:
<div>
<span><img src="http://jsfiddle.net/img/logo.png" /></span>
</div>
<div>
<span> text </span>
</div>
Put your img in a span, the image is a replaced element, it cannot contain children content, hence, vertical-align will not work.
CSS:
div {
width:200px;
height:200px;
background-color:red;
display:table;
margin:10px;
}
span {
display:table-cell;
vertical-align:middle;
}
See demo at: http://jsfiddle.net/audetwebdesign/Fz6Nj/
There are several ways of doing this, you could also apply display: table-cell to the parent div element, but that would be a different approach.
In order to vertically align an image inside a table cell you need to give the image a display of block.
display: block
margin: 0 auto
the margin: 0 auto is to align the image to the center. If you want the image left aligned then don't include this. If you want the image right aligned you can add:
float: right
Thanks,
G
You can try by adding -> line-height: 200px; in the span style section, I think it might work;

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/

CSS Container DIv Height. Floating DIV questions

Can you force a container DIV height to accomodate two floated div children? Is there a fancy trick I can use to do that? I am trying to make two equally sized divs inside the parent div. I would like them to appear side by side with a little whitespace between them. Child2 tends to pop out and go below Child1. Note Child2 contains a table. Should I be floating?
HTML:
<div id="parent">
<div id="child1"></div>
<div id="child2">
<table><tr><td>content</td></tr></table>
</div>
</div>
CSS:
div#parent
{
background-color: #C6E4E0;
border: solid 3px #017E6F;
font-family: Arial;
font-size: 10pt;
font-weight: bold;
padding-left: 5px;
padding-right: 5px;
width:99%;
}
div#parent div
{
width:49%;
float:right;
padding:3px;
}
div#parent div:first-child
{
float:left;
}
This is not a clearfix issue guys, his problem is that his two floated divs are not appearing side by side.
First of all, you do not need to set the width of the parent div, divs are block elements which means they automatically adjust their width to take up the full width of their parent (in this case, presumably the parent of div#parent is the body).
Because you are setting the width explicitly AND giving it padding, it can potentially extend BEYOND the body. That doesn't really matter, but if you apply this same knowledge to the child floated divs and you can see why the right one might get bumped down to the bottom.
First, if you are explicitly setting the widths of the divs to a percentage, you do not need to add padding. Because you are dealing with percentage widths, it is better to add padding to the content of the divs rather than the divs themselves, because padding is ADDED to the width. Therefore, if you added 10px padding to a div that had a 49% width in a 100px parent, it would have a width of 49px + 10px + 10px (2 sides) for a total calculated width of 69px.
Since you didn't post your markup and content or which browser you are testing in, I can't say exactly why the div is being bumped down. There are two likely possibilities.
You are using IE, which allows tables to extend beyond its parent div which will cause breakage. Try explicitly setting the table width to a percentage of its parent or something like that.
The 49% width + padding = greater than [parent-width] - [left-div-width]. This will cause it to get bumped down because the left div and right div are too wide for the parent width.
I use the clearfix class.
.clearfix:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
.clearfix {
display: inline-block;
}
/* Hides from IE-mac \*/
/** html .clearfix {height: 1%;}*/
.clearfix {
display: block;
}
/* End hide from IE-mac */
then just use the class in every floated-element container.
#container { width:200px; }
.floated { width:100px; float:left; }
.clear { clear:both; }
<div id="container">
<div class="floated">A</div>
<div class="floated">B</div>
<div class="clear"></div>
</div>
I am not a fan of clear: both;, I rather do this in Jonathan Sampsons example:
#container { width:200px; overflow: hidden; }
.floated { width:100px; float:left; }
<div id="container">
<div class="floated">A</div>
<div class="floated">B</div>
</div>
By the way, you want
div#parent > div { float:left; }
instead of
div#parent div:first-child { float:left; }
which is still not IE6 friendly, but it will float both child DIVs.

Resources