Height of a floating container - html

I have a question regarding a simple case where you have 2 floating elements inside a div container, and you want the height of the container to adjust appropriately.
I know that there are multiple ways to achieve this, namely using a clearing div, a clearing :after pseudo-element, setting overflow:hidden, or (like in the example below) floating the container div.
.container {
float: left;
}
.container img {
float: left;
}
.container p {
float: right;
}
<div class="container">
<img src="somePic.jpg" />
<p>Some text</p>
</div>
I know that the container div (if not floated) does not adjust the height because its children (floated) are not part of the normal flow. Can someone explain why floating the container fixes this?

Set your container display property to block or inline-block and overflow:visible makes it. See the sample code below:
.container {
display: inline-block;
overflow: visible;
float: left;
padding: 16px;
background-color: #00ff00;
}
.container img {
float: left;
}
.container p {
float: right;
}
<div class="container">
<img src="http://www.petsworld.in/blog/wp-content/uploads/2014/09/cute-kittens.jpg" />
<p>Some text</p>
</div>

#Alexander already gives you a possible solution to your problem, but if I correctly understood, you wanted to know "why" floating the container could solve the problem.
I searched around and I did not find an exaustive answer, anyway I found reasons to avoid this method due to various drawbacks.
In general, we can say that floating an element extract it from normal document flow, and this is why its container naturally collapse to 0 height. Floating it too, extract this last one from document flow either, creating a different context that could contain floated children.

Related

Show Centered Text Next to Site's Icon

Complete noob here with HTML/CSS.
I'm trying to get something like this : http://imgur.com/Bc72V4M
Here is my code:
<div id="topbar">
<div class="image">
<img src="images/ghwlogo.png">
</div>
<div class="text">
<h1>TEXT TEXT TEXT TEXT TEXT</h1>
</div>
</div>
I've tried floating the div topbar, then display-inline but it never displays horizontally.
I'm so confused. Following tutorials is easy-peasy, but when you need to figure out how to do this yourself, it's completely different.
I think I'm missing a step somewhere. I feel like this should be really easy but it's not.
img {
display: inline;
vertical-align: middle;
}
.subhead {
display: inline;
vertical-align: middle;
}
<div>
<img src="http://dummyimage.com/100x100/000/fff"/>
<h1 class='subhead'>
TEXT
</h1>
</div>
I removed some HTML; I only add more when I can't think of how to get the effect with just CSS. You can add some back, but you may have to set display: inline on some inner elements then.
Generally, a few different ways of putting elements horizontally:
Floating: Removes it from standard flow layout, and may interfere with the root element's total height. Was previously the preferred method of placement but I feel like there are better alternatives.
Display Inline: Treats an element a bit like text. Cannot have a custom height or various other attributes.
Display Inline-Block: Often a "fix-all" for me when I want something laid out horizontally, but to have other styling aspects like height, border, etc.
Position Absolute: You can make a higher element a "relative element" for absolute positioning by setting position: relative on it. Like floating this takes it out of layout, but it can even overlap elements; useful for certain things. Don't rely on absolute pixel amounts too much.
In my case, once things are laid out horizontally, vertical alignment is the next issue. Remember that adding content could make this block very very tall, so you can't just say "vertical-align to the bottom of the thing". Think of all elements in the div as simply letters in a paragraph; for the smaller ones, you're telling it how to align that one letter. For the biggest ones, you're telling it where that "letter" is aligned compared to the others. So, it's important to set vertical alignment how you want it on the image as well.
EDIT: updated answer per #Katana314 answer. I've maintained the OP's markup.
#topbar {
width: 100%;
overflow: hidden;
}
.image {
display: inline-block;
vertical-align: middle;
border: 5px solid black;
height: 100px;
width: 100px;
}
.text {
display: inline-block;
vertical-align: middle;
}
Fiddle: https://jsfiddle.net/dgautsch/che0dtfk/
You could make the image and the text a separate div and then have both of them under the inline-block attribute. The text div would need to have a position: absolute attribute, though, for formatting purposes.
After viewing the Fiddle, you can adjust the left position attribute accordingly to generate space. Here is the link: https://jsfiddle.net/kuLLd866/.
HTML:
<body>
<div class="image">
<img src="http://gfx2.poged.com/poged/game_logo_default_fix.png?2492">
</div>
<div class="imagetext">
<h1>Text text text</h1>
</div>
</body>
CSS:
.image {
display: inline-block;
}
.imagetext {
position: absolute;
top: 50px;
display: inline-block;
}

Avoid right-floated DIV wrapping without adding any height in container

I'm trying to have a toolbar always aligned to the right within a DIV without adding any height. The problem I'm finding is making this work both when the box has 100% width and when the width is determined by content. The HTML looks something similar to this:
<div class="box">
<div class="title">
float right
</div>
<div class="toolbar">
<button>1</button>
<button>2</button>
<button>3</button>
<button>4</button>
</div>
</div>
I managed to make it work in Firefox, but Chrome wraps the toolbar when there is not enough space for it instead of increasing the width of the container.
.box {
border: 1px solid #ccc;
display: inline-block;
margin: 5px 0 15px;
}
.title {
display: inline-block;
}
.toolbar {
background: #eee;
float: right;
margin-left: 25px;
}
I would like to find a single set of rules to achieve this regardless the width of the container, but I'm out of ideas unless I use some extra class to differentiate both cases. Also, I'm trying to avoid using overflow or clearfix because I don't want the toolbar to affect the height of the box.
In this fiddle I show all combinations I have tried: http://jsfiddle.net/omegak/c4y4t/2/
You can try this, This worked for me.
.title {
float:left;
}
See if this is the desired output
Updated the below css and added clearfix class to the parent div
.title {
float:left;
}
Add the following CSS and clear the floats on first Div.
.title {
float:left;
}
Here is the demo
I got it working in the end with a little hack.
I gave up on trying the title not to be float: left. Then, to prevent the box to have no height I added overflow: hidden to it. Finally, the hack consists on setting margin-bottom: -999px on the toolbar to prevent it from adding any extra height to the box.
Here is the solution: http://jsfiddle.net/c4y4t/8/

Best solution for horizontal alignment in a webpage?

friends,
I decided to ask this because I've seen many answers on the internet, but no one seems to be a definitive answer.
In out HTML documents we have many elements one inside another. Eventually we'll want to add paddings and margins to these elements.
So, what if we want to have all content horizontally aligned to the center of the page? If the content has 1000px of width and the screen resolution will change from device to device, the most common solution is something like (will work on netscape based browsers):
body{
width: 100%;
}
#content{
width: 1000px;
margin: 0 auto;
}
But if we have lots of other elements inside the #content element, like a table made of DIV elements, we start to face some problems. The parent's height will not adjust to its children's height and padding and margin will not work properly (if we inspect the element we will see that the width and height is not behaving as expected) unless we add some new rules.
I use float: left but then the headache starts! When I add float: left only those elements will work fine, but the parents will not. If I add float: left to an element that already has margin: 0 auto set, it will no longer be aligned to the center of the page...
I've seen some solutions using text-align: center to the parent and display: inline-block; float: none; to the element we want to be aligned to the center. But it also has many problems (for example, we can't set the float rule)
How do you deal with this problem guys?
You need to use clear after you use float on elements in order to 'clear the floats' and make the height propagate up to its parents. You can use clear:left (or right) to just clear float:left elements but typically it's fine to just use clear:both.
In the below example there are two versions of clearfixes, one that uses a pseudo-element on the container and another that is just another element.
Demo
HTML
<div id="content">
<nav>
<ul>
<li>Home</li>
<li>Second</li>
<li>Third</li>
</ul>
</nav>
<div class="float-me">Test1</div>
<div class="float-me">Test2</div>
<div class="clear"></div>
</div>
CSS
#content {
width: 500px;
margin: 0 auto;
}
li {
float:left;
}
/* our pseudo-element clearfix */
ul:after {
display: block;
content: "";
clear: both;
}
.float-me {
float:left;
}
.clear {
clear:both;
}

display: inline-block not working unless first div floated:left

I am a relative novice in the world of CSS so please excuse my ignorance! I am attempting to use the following CSS to align two divs horizontally:
.portrait {
position: relative;
display:inline-block;
width: 150px;
height: 200px;
padding: 20px 5px 20px 5px;
}
.portraitDetails {
position: relative;
display:inline-block;
width: 830px;
height: 200px;
padding: 20px 5px 20px 5px;
}
Unfortunately, unless I remove the display: inline-block from the .portrait class and replace it with float:left the .portraitDetails div block appears underneath the first div block. What on earth is going on?
Since you provided a working example, the problem seems to be more clear now.
What you have to do is simply remove display: inline-block and width: 830px properties from the right div. Of course remember to NOT add the float property to it.
People sometimes forget what is the purpose of the float property. In your case it is the image which should have float property and the image only. The right div will remain 100% wide by default while the image will float it from the left.
HINT: If the text from the div is long enough to float underneath the image and you want to keep it "indented" at the same point then add the margin to the div with a value equal to the image's width.
The problem with display: inline-block; is that the siblings having this property are always separated by a single white-space but only if there are any white-spaces between their opening and closing tags.
If the parent container has fixed width equal to the sum of the widths of these two divs, then they won't fit because this tiny white-space pushes the second div to the next line. You have to remove the white-space between the tags.
So, instead of that:
<div class="portrait">
...
</div>
<div class="portraitDetails">
...
</div>
you have to do that:
<div class="portrait">
...
</div><div class="portraitDetails"> <!-- NO SPACE between those two -->
...
</div>

CSS two divs next to each other

I want to put two <div>s next to each other. The right <div> is about 200px; and the left <div> must fill up the rest of the screen width? How can I do this?
You can use flexbox to lay out your items:
#parent {
display: flex;
}
#narrow {
width: 200px;
background: lightblue;
/* Just so it's visible */
}
#wide {
flex: 1;
/* Grow to rest of container */
background: lightgreen;
/* Just so it's visible */
}
<div id="parent">
<div id="wide">Wide (rest of width)</div>
<div id="narrow">Narrow (200px)</div>
</div>
This is basically just scraping the surface of flexbox. Flexbox can do pretty amazing things.
For older browser support, you can use CSS float and a width properties to solve it.
#narrow {
float: right;
width: 200px;
background: lightblue;
}
#wide {
float: left;
width: calc(100% - 200px);
background: lightgreen;
}
<div id="parent">
<div id="wide">Wide (rest of width)</div>
<div id="narrow">Narrow (200px)</div>
</div>
I don't know if this is still a current issue or not but I just encountered the same problem and used the CSS display: inline-block; tag.
Wrapping these in a div so that they can be positioned appropriately.
<div>
<div style="display: inline-block;">Content1</div>
<div style="display: inline-block;">Content2</div>
</div>
Note that the use of the inline style attribute was only used for the succinctness of this example of course these used be moved to an external CSS file.
Unfortunately, this is not a trivial thing to solve for the general case. The easiest thing would be to add a css-style property "float: right;" to your 200px div, however, this would also cause your "main"-div to actually be full width and any text in there would float around the edge of the 200px-div, which often looks weird, depending on the content (pretty much in all cases except if it's a floating image).
EDIT:
As suggested by Dom, the wrapping problem could of course be solved with a margin. Silly me.
The method suggested by #roe and #MohitNanda work, but if the right div is set as float:right;, then it must come first in the HTML source. This breaks the left-to-right read order, which could be confusing if the page is displayed with styles turned off. If that's the case, it might be better to use a wrapper div and absolute positioning:
<div id="wrap" style="position:relative;">
<div id="left" style="margin-right:201px;border:1px solid red;">left</div>
<div id="right" style="position:absolute;width:200px;right:0;top:0;border:1px solid blue;">right</div>
</div>
Demonstrated:
left
right
Edit: Hmm, interesting. The preview window shows the correctly formatted divs, but the rendered post item does not. Sorry then, you'll have to try it for yourself.
I ran into this problem today. Based on the solutions above, this worked for me:
<div style="width:100%;">
<div style="float:left;">Content left div</div>
<div style="float:right;">Content right div</div>
</div>
Simply make the parent div span the full width and float the divs contained within.
UPDATE
If you need to place elements in a row, you can use Flex Layout. Here you have another Flex tutorial. It's a great CSS tool and even though it is not 100% compatible, each day its support is getting better. This works as simple as:
HTML
<div class="container">
<div class="contentA"></div>
<div class="contentB"></div>
</div>
CSS
.container {
display: flex;
width: 100%;
height: 200px;
}
.contentA {
flex: 1;
}
.contentB {
flex: 3;
}
And what you get here is a container with a total size of 4 units, that share the space with its children in a relation of 1/4 and 3/4.
I have done an example in CodePen that solves your problem. I hope it helps.
http://codepen.io/timbergus/pen/aOoQLR?editors=110
VERY OLD
Maybe this is just a nonsense, but have you tried with a table? It not use directly CSS for positioning the divs, but it works fine.
You can create a 1x2 table and put your divs inside, and then formatting the table with CSS to put them as you want:
<table>
<tr>
<td>
<div></div>
</td>
<td>
<div></div>
</td>
</tr>
</table>
Note
If you want to avoid using the table, as said before, you can use float: left; and float: right;and in the following element, don't forget to add a clear: left;, clear: right; or clear: both; in order to have the position cleaned.
div1 {
float: right;
}
div2 {
float: left;
}
This will work OK as long as you set clear: both for the element that separates this two column block.
I ran into the same problem and Mohits version works. If you want to keep your left-right order in the html, just try this. In my case, the left div is adjusting the size, the right div stays at width 260px.
HTML
<div class="box">
<div class="left">Hello</div>
<div class="right">World</div>
</div>
CSS
.box {
height: 200px;
padding-right: 260px;
}
.box .left {
float: left;
height: 200px;
width: 100%;
}
.box .right {
height: 200px;
width: 260px;
margin-right: -260px;
}
The trick is to use a right padding on the main box but use that space again by placing the right box again with margin-right.
I use a mixture of float and overflow-x:hidden. Minimal code, always works.
https://jsfiddle.net/9934sc4d/4/ - PLUS you don't need to clear your float!
.left-half{
width:200px;
float:left;
}
.right-half{
overflow-x:hidden;
}
As everyone has pointed out, you'll do this by setting a float:right; on the RHS content and a negative margin on the LHS.
However.. if you don't use a float: left; on the LHS (as Mohit does) then you'll get a stepping effect because the LHS div is still going to consume the margin'd space in layout.
However.. the LHS float will shrink-wrap the content, so you'll need to insert a defined width childnode if that's not acceptable, at which point you may as well have defined the width on the parent.
However.. as David points out you can change the read-order of the markup to avoid the LHS float requirement, but that's has readability and possibly accessibility issues.
However.. this problem can be solved with floats given some additional markup
(caveat: I don't approve of the .clearing div at that example, see here for details)
All things considered, I think most of us wish there was a non-greedy width:remaining in CSS3...
This won't be the answer for everyone, since it is not supported in IE7-, but you could use it and then use an alternate answer for IE7-. It is display: table, display: table-row and display: table-cell. Note that this is not using tables for layout, but styling divs so that things line up nicely with out all the hassle from above. Mine is an html5 app, so it works great.
This article shows an example: http://www.sitepoint.com/table-based-layout-is-the-next-big-thing/
Here is what your stylesheet will look like:
.container {
display: table;
width:100%;
}
.left-column {
display: table-cell;
}
.right-column {
display: table-cell;
width: 200px;
}
To paraphrase one of my websites that does something similar:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<style TYPE="text/css"><!--
.section {
_float: right;
margin-right: 210px;
_margin-right: 10px;
_width: expression( (document.body.clientWidth - 250) + "px");
}
.navbar {
margin: 10px 0;
float: right;
width: 200px;
padding: 9pt 0;
}
--></style>
</head>
<body>
<div class="navbar">
This will take up the right hand side
</div>
<div class="section">
This will fill go to the left of the "navbar" div
</div>
</body>
</html>
just use a z-index and everything will sit nice. make sure to have positions marked as fixed or absolute. then nothing will move around like with a float tag.