floating elements on non-floated element: - html

I have a two column layout, one of them is floated left, another is not:
<div id="left">
LEFT
</div>
<div id="right">
RIGHT
</div>
And the CSS is:
#left {
float: left;
width: 200px;
background: yellow;
}
#right {
margin-left: 200px;
background: orange;
}
In the right element that is not floated, I have a markup like this:
<div id="nav">
<div class="item">LINK</div>
<div class="item">LINK</div>
<div class="item">LINK</div>
<div class="item">LINK</div>
<div class="item">LINK</div>
<div class="clear"></div>
</div>
<h1>Welcome World</h1>
And the CSS for nav and item is (as you see, the item is floated):
#nav {
background: blue;
}
.item {
background: green;
float: left;
margin-right: 10px;
}
And my clear element is:
.clear {
clear: both;
}
And, at last, I get this result:
I think that the problem is with my clear element which is clearing the floated element too (#left).
But I expected to get this result:
Here is the fiddle demo

Instead of adding unneeded mark-up in your HTML, you can just add overflow: hidden; to #nav. This will create a new block-formatting context for the list-items within #nav, as floated elements are taken out of the normal flow (its in-flow container won't respect their height, notice the <body> not extending down to #left in my fiddle)
From the Visual Formatting Model, 9.4.1:
Floats, absolutely positioned elements, block containers (such as inline-blocks, table-cells, and table-captions) that are not block boxes, and block boxes with 'overflow' other than 'visible' (except when that value has been propagated to the viewport) establish new block formatting contexts for their contents.
#nav {
background: blue;
overflow: hidden; /* Creates a new block-formatting context
for floated descendants */
}
http://jsfiddle.net/bJFUj/9/

Working jsFiddle Demo
Make your #nav element to inline-block and set the width to 100%:
#nav {
background: blue;
display: inline-block;
width: 100%;
}

I did this a different way. You can move the clear to one of two different places (which gets you different results), but the overall problem is solved. Pick whichever one is more suitable.
(http://jsfiddle.net/bJFUj/4/ OR http://jsfiddle.net/bJFUj/6/)
In both cases I basically change nav's css (because no background would show otherwise)
#nav {
background: blue;
overflow: hidden;
}
I'd just move the clear to the element containing both div#left and div#right. Putting it inside div#right seems to be creating some interesting effects with regards to the height of div#right.

Example on jsFiddle
Removed from #nav
<div class="clear"></div>
Added style to #nav
overflow: hidden;

Clearing floats are concerned with floated elements but you have cleared the element that you have not floated either left or right i.e. #nav. So add float: left; to your #nav then only your <div class="clear"></div> will work as what you want.
demo

Related

Increase container's height to the hightest element when with float: left, and float: right

I have a container element and two sub elements in it placed in as float: left, and float: right. The left-floated element has one line of text. The right-floated element has two lines separated by . Now, when this is deployed, the container takes up on the height of the left-floated element, so the second line in the right-floated element appears outside the container. What can we do to prevent this from happening?
What all you need is to have a display: inline-block; or overflow: hidden; property in the container. Check this JSFiddle
<div id="m">
<div class="a">a<br>c</div>
<div class="b">b</div>
</div>
#m{
background-color: gray;
width: 100%;
overflow: hidden;
}
.a{
float: left;
}
.a{
float: right;
}
Use a clearfix implementation. That fix is usually attached by a class name to the parent DIV that you want to expand to contain floated child elements. For example see http://www.webtoolkit.info/css-clearfix.html

Some doubts related to the clear property on the footer in an HTML\CSS template

I have implement the following fixed tabless layout using HTML+CSS: http://onofri.org/example/WebTemplate/
(I have to finalize some settings)
This layout have two floatted columns #content and #sidebar and under these columns there is placed the footer div #footcontainer
Ok, so I have to clear the elements that I would to place under the tow columns (bring back the elements in the normal flow of the document), to do this I use the clear CSS property.
I have read that I could do that in some differents way.
In my example I have created an empty div having id clearer2 that have the following CSS settings:
#clearer2{
clear: both;
}
This work well, but I know that I could also clear directly the footercontainer, in this way:
#footcontainer {
clear: both;
width: 100%;
min-height: 200px;
height: auto !important;
height: 200px;
background: #4f4f4f url(../images/bgfooter.jpg) repeat-x 0 0;
box-shadow: 0 -13px 25px 5px #b2b2b2;
}
At logic level should be the same thing because I set the clear: both; property on an item and then this property is valid for all the successive items. But reading online it seems to me that the first solution is better then the second one. Why is better to creat a new item (as an empty div) that clear then do it directly on the appropriate element (in the example the div #footercontainer)
The solution that I have use is a valid solution?
Tnx
Andrea
From the sample page, you have two versions.
HTML with empty clearer div
<div id="container">
<div id="content">...</div>
<div id="sidebar">...</div>
<div class="clearer"></div>
</div>
<div id="footcontainer">
<div id="footer">...</div>
</div>
CSS:
#content, #sidebar { float: left; }
.clearer {
clear: both;
visibility: hidden;
}
and without an empty div
<div id="container">
<div id="content">...</div>
<div id="sidebar">...</div>
</div>
<div id="footcontainer" class="clearer">
<div id="footer">...</div>
</div>
CSS:
#content, #sidebar { float: left; }
.clearer { clear: both; }
Both approaches are valid and the visual result is the same.
But in the first example, the container has a non-zero height, because of the empty clearer div. Because the floating divs are removed from the normal flow, the container in the second example has no content and a zero height.

CSS - Float and Background Size Relation

Currently, I'm working on a navigation and I've encountered this issue:
The content of the navigation is floated to left. When I try to set the background color for the navigation itself, it does not work. Look at this example:
http://cssdeck.com/labs/qknohqxe
When the float:left is removed, the background color becomes visible, however, the "form" of the navigation is destroyed.
I'm pretty sure I'm missing an important point as I'm trying to reach to this simple point where both form and background color are preserved as I wanted.
My guess is that, there is a relation between the floated content, and the size of the carrier (#nav in my case).
Needing suggestions/workarounds for this issue.
Add this to .group:
overflow:auto;
That's it.
There is also another solution: adding a clear:both; element after all floating divs. But it's a bit more dirty:
<div class="container">
<div class="floating div"></div>
<div class="floating div"></div>
<div class="floating div"></div>
<div style="clear:both;"></div>
</div>
It always happens when you use floating divs. The container doesn't care about floating elements so it is like an empty container unless you use one of the mentioned solutions.
On the parent container (.group in your case), add overflow: auto or set a fixed height.
This happens because floated, as well as absolutely positioned elements are, by default, excluded from the document flow and thus are ignored when positioning the following elements.
Add a height to your .group.
.group{
height: 300px;
background-color: blue;
}
When you float objects it takes it out of the document flow. Meaning the parent object has no relation to the height of the child elements.
By setting a height you're forcing the container to go down.
Alternatively you can add an overflow to the container .group to force it to look for the height.
.group{
overflow: hidden;
background-color: blue;
}
Here's working CSS declaration.
.group{
background-color: blue;
float: left;
width: 200px;
}
You need to understand floating and positioning of nested elements.
Just add a clear both; to an extra element:
<div id="nav">
<div class="group">
<div class="button">Button1</div>
<div class="button">Button2</div>
<div class="button small">Button3</div>
<div class="button small">Button4</div>
<div class="button">Button5</div>
<br class="clear" />
</div>
</div>
#nav{
width: 240px;
}
.button{
float:left;
border-radius: 20px;
width: 200px;
height: 50px;
margin-top: 10px;
background-color: red;
text-align: center;
line-height: 50px;
}
.group{
background-color: blue;
}
.small{
width: 100px;
}
.clear
{
clear: both;
}

How can I expand floated child div's height to parent's height?

I have the page structure as:
<div class="parent">
<div class="child-left floatLeft">
</div>
<div class="child-right floatLeft">
</div>
</div>
Now, the child-left DIV will have more content, so the parent DIV's height increases as per the child DIV.
But the problem is child-right height is not increasing. How can I make its height as equal to it's parent?
For the parent element, add the following properties:
.parent {
overflow: hidden;
position: relative;
width: 100%;
}
then for .child-right these:
.child-right {
background:green;
height: 100%;
width: 50%;
position: absolute;
right: 0;
top: 0;
}
Find more detailed results with CSS examples here and more information about equal height columns here.
A common solution to this problem uses absolute positioning or cropped floats, but these are tricky in that they require extensive tuning if your columns change in number+size, and that you need to make sure your "main" column is always the longest. Instead, I'd suggest you use one of three more robust solutions:
display: flex: by far the simplest & best solution and very flexible - but unsupported by IE9 and older.
table or display: table: very simple, very compatible (pretty much every browser ever), quite flexible.
display: inline-block; width:50% with a negative margin hack: quite simple, but column-bottom borders are a little tricky.
1. display:flex
This is really simple, and it's easy to adapt to more complex or more detailed layouts - but flexbox is only supported by IE10 or later (in addition to other modern browsers).
Example: http://output.jsbin.com/hetunujuma/1
Relevant html:
<div class="parent"><div>column 1</div><div>column 2</div></div>
Relevant css:
.parent { display: -ms-flex; display: -webkit-flex; display: flex; }
.parent>div { flex:1; }
Flexbox has support for a lot more options, but to simply have any number of columns the above suffices!
2.<table> or display: table
A simple & extremely compatible way to do this is to use a table - I'd recommend you try that first if you need old-IE support. You're dealing with columns; divs + floats simply aren't the best way to do that (not to mention the fact that multiple levels of nested divs just to hack around css limitations is hardly more "semantic" than just using a simple table). If you do not wish to use the table element, consider css display: table (unsupported by IE7 and older).
Example: http://jsfiddle.net/emn13/7FFp3/
Relevant html: (but consider using a plain <table> instead)
<div class="parent"><div>column 1</div><div>column 2</div></div>
Relevant css:
.parent { display: table; }
.parent > div {display: table-cell; width:50%; }
/*omit width:50% for auto-scaled column widths*/
This approach is far more robust than using overflow:hidden with floats. You can add pretty much any number of columns; you can have them auto-scale if you want; and you retain compatibility with ancient browsers. Unlike the float solution requires, you also don't need to know beforehand which column is longest; the height scales just fine.
KISS: don't use float hacks unless you specifically need to. If IE7 is an issue, I'd still pick a plain table with semantic columns over a hard-to-maintain, less flexible trick-CSS solution any day.
By the way, if you need your layout to be responsive (e.g. no columns on small mobile phones) you can use a #media query to fall back to plain block layout for small screen widths - this works whether you use <table> or any other display: table element.
3. display:inline block with a negative margin hack.
Another alternative is to use display:inline block.
Example: http://jsbin.com/ovuqes/2/edit
Relevant html: (the absence of spaces between the div tags is significant!)
<div class="parent"><div><div>column 1</div></div><div><div>column 2</div></div></div>
Relevant css:
.parent {
position: relative; width: 100%; white-space: nowrap; overflow: hidden;
}
.parent>div {
display:inline-block; width:50%; white-space:normal; vertical-align:top;
}
.parent>div>div {
padding-bottom: 32768px; margin-bottom: -32768px;
}
This is slightly tricky, and the negative margin means that the "true" bottom of the columns is obscured. This in turn means you can't position anything relative to the bottom of those columns because that's cut off by overflow: hidden. Note that in addition to inline-blocks, you can achieve a similar effect with floats.
TL;DR: use flexbox if you can ignore IE9 and older; otherwise try a (css) table. If neither of those options work for you, there are negative margin hacks, but these can cause weird display issues that are easy to miss during development, and there are layout limitations you need to be aware of.
For the parent:
display: flex;
For children:
align-items: stretch;
You should add some prefixes, check caniuse.
I found a lot of answers, but probably the best solution for me is
.parent {
overflow: hidden;
}
.parent .floatLeft {
# your other styles
float: left;
margin-bottom: -99999px;
padding-bottom: 99999px;
}
You can check other solutions here http://css-tricks.com/fluid-width-equal-height-columns/
Please set parent div to overflow: hidden
then in child divs you can set a large amount for padding-bottom. for example
padding-bottom: 5000px
then margin-bottom: -5000px
and then all child divs will be the height of the parent.
Of course this wont work if you are trying to put content in the parent div (outside of other divs that is)
.parent{
border: 1px solid black;
overflow: hidden;
height: auto;
}
.child{
float: left;
padding-bottom: 1500px;
margin-bottom: -1500px;
}
.child1{
background: red;
padding-right: 10px;
}
.child2{
background: green;
padding-left: 10px;
}
<div class="parent">
<div class="child1 child">
One line text in child1
</div>
<div class="child2 child">
Three line text in child2<br />
Three line text in child2<br />
Three line text in child2
</div>
</div>
Example: http://jsfiddle.net/Tareqdhk/DAFEC/
Does the parent have a height? If you set the parents height like so.
div.parent { height: 300px };
Then you can make the child stretch to the full height like this.
div.child-right { height: 100% };
EDIT
Here is how you would do it using JavaScript.
CSS table display is ideal for this:
.parent {
display: table;
width: 100%;
}
.parent > div {
display: table-cell;
}
.child-left {
background: powderblue;
}
.child-right {
background: papayawhip;
}
<div class="parent">
<div class="child-left">Short</div>
<div class="child-right">Tall<br>Tall</div>
</div>
Original answer (assumed any column could be taller):
You're trying to make the parent's height dependent on the children's height and children's height dependent on parent's height. Won't compute. CSS Faux columns is the best solution. There's more than one way of doing that. I'd rather not use JavaScript.
I used this for a comment section:
.parent {
display: flex;
float: left;
border-top:2px solid black;
width:635px;
margin:10px 0px 0px 0px;
padding:0px 20px 0px 20px;
background-color: rgba(255,255,255,0.5);
}
.child-left {
align-items: stretch;
float: left;
width:135px;
padding:10px 10px 10px 0px;
height:inherit;
border-right:2px solid black;
}
.child-right {
align-items: stretch;
float: left;
width:468px;
padding:10px;
}
<div class="parent">
<div class="child-left">Short</div>
<div class="child-right">Tall<br>Tall</div>
</div>
You could float the child-right to the right, but in this case I've calculated the widths of each div precisely.
I have recently done this on my website using jQuery. The code calculates the height of the tallest div and sets the other divs to the same height. Here's the technique:
http://www.broken-links.com/2009/01/20/very-quick-equal-height-columns-in-jquery/
I don't believe height:100% will work, so if you don't explicitly know the div heights I don't think there is a pure CSS solution.
If you are aware of bootstrap you can do it easily by using 'flex' property.All you need to do is pass below css properties to parent div
.homepageSection {
overflow: hidden;
height: auto;
display: flex;
flex-flow: row;
}
where .homepageSection is my parent div.
Now add child div in your html as
<div class="abc col-md-6">
<div class="abc col-md-6">
where abc is my child div.You can check equality of height in both child div irrespective of border just by giving border to child div
<div class="parent" style="height:500px;">
<div class="child-left floatLeft" style="height:100%">
</div>
<div class="child-right floatLeft" style="height:100%">
</div>
</div>
I used inline style just to give idea.
I can see that the accepted answer uses position: absolute; instead of float: left. In case you want to use float: left with the following structure,
<div class="parent">
<div class="child-left floatLeft"></div>
<div class="child-right floatLeft"></div>
</div>
Give position: auto; to the parent so that it will contain its children height.
.parent {
position: auto;
}
.floatLeft {
float: left
}
I learned of this neat trick in an internship interview. The original question is how do you ensure the height of each top component in three columns have the same height that shows all the content available. Basically create a child component that is invisible that renders the maximum possible height.
<div class="parent">
<div class="assert-height invisible">
<!-- content -->
</div>
<div class="shown">
<!-- content -->
</div>
</div>

centering a div between one that's floated right and one that's floated left

I have a page in which a header consists of three divs - one that's floated to the left, one that's floated to the right, and one that's in between them. I'd like for that central div to be centered, yet sadly float: center doesn't exist and I can't just float it to the left and add padding as it'd have to change depending on the window size.
Is there something simple I'm overlooking? Or how would I do such a thing?
Update:
In addition, I'd like to find a way of centering that middle div in the space between the divs in case that looks better.
If you have two floated divs, then you know the margins. The problem is that the float:right div should be put before the middle div. So basically you will have:
left-floated | right-floated | centered
Now, about the margins: usually you can just use margin:0 auto, right? The problem is that right now you know the values of the margins: floated divs! So you just need to use:
margin:0 right-floated-width 0 left-floated-width
That should work.
Years later edit
Meanwhile, a new toy is in town: flexbox. The support is fairly good (i.e. if you don't need to support lower than IE 10) and the ease of use is way over floats.
You can see a very good flexbox guide here. The example you need is right here.
Indeed, the important part is that the centered div come after the left and right divs in the markup. Check out this example, it uses margin-left: auto and margin-right: auto on the centered div, which causes it to be centered.
<html>
<head>
<style type="text/css">
#left
{
float: left;
border: solid 1px red;
}
#mid
{
margin-left: auto;
margin-right: auto;
border: solid 1px red;
}
#right
{
float: right;
border: solid 1px red;
}
</style>
</head>
<body>
<div id="left">
left
</div>
<div id="right">
right
</div>
<div id="mid">
mid
</div>
</body>
</html>
Here's a JS Bin to test: http://jsbin.com/agewes/1/edit
Usually you can use flexbox instead of floats:
https://jsfiddle.net/h0zaf4Lp/
HTML:
<div class="container">
<div>left</div>
<div class="center">center</div>
<div>right</div>
</div>
CSS:
.container {
display: flex;
}
.center {
flex-grow: 1;
}
The element with the centered content needs to be specified after both floated elements. After that, simply set the middle element to text-align: center. The text in the centered element will squeeze in between the floats.
See here:
http://jsfiddle.net/calvintennant/wjjeR/
Try this (make sure to use better class names):
.left {
float:left;
width:200px;
}
.right{
float:right;
width:200px;
}
.center {
overflow:hidden;
zoom:1;
}
The center div will fit between the two floats.
If you want to create a gutter between that centered div and the two floats, then use margin on the floats, not on the center div.
Because of "zoom", the CSS will not validate, but that layout will work in IE 5.5 and 6.
Note that source order is important here: the two floats must come first, then your "centered" div.
In some cases, you have a limitation and cannot change the page markup by moving the middle div after the right-floated div. In that case, follow these instructions:
For container: position: relative
For middle div: position: absolute; left: [containerWidth - middle-width / 2]
I hope you got the idea.
A simple solution without having to change the order of the divs (sometimes we can not do this) could be an absolute positioning for the center div as follows:
.container {
position: relative;
}
.container div {
width: 200px;
background: red;
}
.left {
float: left;
}
.right {
float: right;
}
.center {
position: absolute;
top: 0;
left: 0;
right: 0;
margin: auto;
}
<div class="container">
<div class="left">left</div>
<div class="center">center</div>
<div class="right">right</div>
</div>
https://jsfiddle.net/Helioz/nj548y0g/