CSS container height zero... why not height of contents? - css

I am not seeing any vertical space (specified by the 50px margin in lineitem) between lineitem elements. However, if I add something like height:40px; to lineitem's css format, then both the height and the margin are respected. Why doesn't lineitem just derive the heights of the input and label elements and add the margin to whatever that is?
<div id="checkoutform">
<div class="lineitem">
<input type="text" name="EMAIL">
<label for="EMAIL">Your E-Mail:</label>
</div>
<div class="lineitem">
<input type="text" name="NAME">
<label for="NAME">Your Name:</label>
</div>
</div><!-- #checkoutform -->
And the CSS:
#checkoutform .lineitem {
margin:0px 15px 50px 0px;
clear:both;
}
#checkoutform label {
float: right;
text-align:right;
font-family:"Open Sans";
font-weight:normal;
font-size:14px;
}
#checkoutform input {
width:280px;
float:right;
font-family:"Open Sans";
font-weight:normal;
font-size:14px;
}

It could have to do with the line-height of your element's content (if you've set that elsewhere). All elements in the DOM and "essentially" rendered as text. If you don't have a height set for the element, it assumes the line-height for the calculated height, not necessarily the height of the content. You could essentially "force" the .lineitem height be adding a clearfix element, or adding a clear:both;to one of it's children elements.
I suggest looking in this direction as it seems that floating the element as a means to do layout is not the accepted practice.

Very simple:
You need to clear the floats inside .lineitem.
Add this to your css, this clears the floats with a pseudo element without any need to modify your HTML.
#checkoutform .lineitem:after {
display: table;
clear: both;
content: "";
}
Demo: https://jsfiddle.net/jrkph1ra/
The reason this works:
Floated elements get out of the normal flow of height calculation of their containers.
An element that follows the floated elements with clear:both; will mean that no floating elements are allowed on the left or the right side of that element, it moves the margin edge of the element below the margin edge of all relevant floats, forcing the browser to take into account the height of the floated elements into the height calculation.
This element can be a pseudo element of the parent of the floated elements so no HTML modification is needed.
"Clearing the floats" is a common practice and well-tested.
If you use it frequently you can create a class like clearfix and add that class to all relevant elements.
.clearfix:after {
display: table;
clear: both;
content: "";
}
Then add .clearfix to all relevant elements with floated children.
Demo https://jsfiddle.net/jrkph1ra/1/
display: table; vs display:block;
Both display: table; and display:block; will generate block level elements, the major difference is that table will only expand to the width of its content, in this case a width of 0 but block will extend to the width of its container, so using table minimizes the footprint of this method.

Add "float: left" to .line-item
https://jsfiddle.net/q6ytv3tt/1/
#checkoutform .lineitem {
margin:0px 15px 50px 0px;
clear:both;
float:left;
}

Related

Why can I not set height of a span to 0px?

For some reason setting height to 0px does not actually shrink the element to 0px visually...
<div id="bg">
<div id="animate"><span>WINNER ALERT! Click here to get a million dollars!!!</span></div>
</div>
#bg {
background-color:#898989;
font-family: Helvetica;
padding:20px;
}
span {
border:solid black 1px;
height:0px;
}
#animate {
height: 0px;
}
http://jsfiddle.net/LgKP3/
That is because span is an inline element. Height does not apply to inline element. Inline elements derive their height from the content that is contained in them.
See that here->http://jsfiddle.net/59xjv/
Even height:500px is not applied since the span is inline.
Similarly, it gets applied when you convert it to a block-level element.
See that here->http://jsfiddle.net/59xjv/1/
Hope this helps!!!
Give the <span> tag display: inline-block; and overflow: hidden;.
Fiddle here.
http://jsfiddle.net/LgKP3/1/
You have to set display to inline block, I also set overflow to hidden to hide the contents
span {
border:solid black 1px;
height:0px;
display: inline-block;
overflow: hidden;
}
Span is an inline element not a block level element which means it can't have a height at all.
Regardless the height you assign in the stylesheet for the span, it won't work.
I suggest you use a div with an id or a class of height:0px instead of a span.

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;

Center aligning child divs and deal with float and fill

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)

CSS Vertical align middle

I am trying to vertically align a SPAN element in the middle of a parent element.
This is what I am doing:
I am trying to get both the username and password labels to be vertically aligned (middle) with the input boxes.
This is my HTML code:
<div class="login_field_wrap">
<span>Username</span>
<input type="text" autocomplete="off" spellcheck="off" id="username" name="username">
<div class="clear"></div>
</div>
This is what I have tried:
.clear { clear:both; }
.login_field_wrap span {
float:left; vertical-align:middle; font-size:13px; color:#333; font-weight:bold; }
.login_field_wrap input {
float:right; vertical-align:middle; padding:8px 5px; border:solid 1px #AAA;
margin:0px; width:250px; }
Vertically aligning an image element inside of this wrapping DIV works absolutely fine, well in Chrome anyway, it just won't align with my SPAN!
Any help would be amazing.
Vertical aligning via CSS can be tricky, and while CSS3 brings about a slew of goodies to help with that, CSS3 support is lackluster in the current browser market.
To achieve this effect I set the line-height property of the child element equal to the height of its containing element.
For example, I would use the following CSS:
.login_field_wrap { height:30px; /* or whatever is appropriate for your design */
.login_field_wrap span { height:30px; line-height:30px; }
.login_field_wrap input { height:30px; line-height:30px; }
The only downside of using line-height to vertically align something is if the text overflows onto a second line, in which case your design will essentially break.
Just remove the float property from your span class and set it to display:inline-block and the vertical-align:middle property will work, like so:
.login_field_wrap span {
color: #333333;
display: inline-block;
font-size: 13px;
font-weight: bold;
text-align: left;
vertical-align: middle;
}
Edit: cleaned up your code a bit, here is a demo that should work across browsers.
http://jsfiddle.net/kUe3Y/
I found the easiest way to do this is to set the parent container display property to table and the child display property to table-cell
#parent{
display:table;
}
#child{
display:table-cell;
vertical-align:middle;
}
I was able to get this to vertically align an anchor element inside a div.
I put it into the terms of your question in this jsFiddle.
I have never been able to get vertical-align to work in anything other than <td>s.
A workaround I commonly use would be to define a height for .login_field_wrap, then set the line-height property in your <span> to be equal to .login_field_wrap's height.
I think text-align:center; should work on elements too. If I am not mistaken, that usually works even if not on text.

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