Mixing floating and absolute positioning issues - css

I'm trying to float three elements, no problem there. However in the two outside boxes I need to position an element vertically in the center, so I thought I would wrap them both in another div, float the wrapping divs and then absolute position the elements inside them and set the wrapping elements to position: relative; so it wouldn't mess with the layout and the three elements would stay floated correctly.
However it doesn't seem to have happened that way, the middle element still seems to get shoved all the way to the left.
My CSS:
.line_wrap {
float: left;
position: relative;
width: 366px;
min-width: 366px;
max-width: 366px;
}
.line_wrap .line {
position: absolute;
top: 25px;
left: 0;
width: 366px;
min-width: 366px;
max-width: 366px;
border-top: 1px solid #d9dce6;
}
.title {
float: left;
}
.title h2 {
font-weight: 300;
font-size: 37px;
color: #425080;
}
My HTML:
<div class="fee_header">
<div class="line_wrap">
<div class="line"></div>
</div>
<div class="title">
<h2>Standard Fees</h2>
</div>
<div class="line_wrap">
<div class="line"></div>
</div>
<div class="contentClear"></div>
</div>
Fiddle: http://jsfiddle.net/MN88R/
I'm trying to position the two elements on the sides so that the border of them ends up in the vertical center of the text in the middle.

If I understand what you are trying to achieve correctly, then I think you may be just approaching it from the wrong angle and perhaps should try something other than using the 3 floating boxes.
If your goal is to have the title center to it's parent container, and the border then run across the vertical center of the heading text, I would try something more like this:
CSS
.title {
height:20px;
overflow:visible;
border-bottom:1px solid #d9dce6;
margin-bottom:20px;
}
.title h2 {
font-weight: 300;
font-size: 37px;
color: #425080;
text-align:center;
}
HTML
<div class="fee_header">
<div class="title">
<h2>Standard Fees</h2>
</div>
</div>
Here is a link to a new fiddle:
http://jsfiddle.net/2KDQ4/1/
Just make sure that the font-size of your heading and the container div height are in the proportions that meet your needs. And the bottom-margin on title is set with what ever spacing you need.

Related

Why is float:left required in navigation to keep text center when position:absolute applied to header?

Observed a strange thing with CSS position : absolute in header is that unless there is a float:left in the menu below, the text of the menu is not centered vertically and stays at the top. You can see this by running the snippet given in this page and in full width. I have put a media query for float:none in lower screen width which cancels the float:left in higher screen-widths.
Now, why is this behaviour ? Why is float:left keeping the menu text center vertically when position:absolute is applied to header and vice-versa ? I did not find anything on this on searching.
Edit -
Some answers are saying that this is happening due to "collapsing" of margins. But they are not explaining why the h1 of header is not "collapsing" and behaving this way ? Why only the h1 of menu is "collapsing" ? It seems more of a selecting overlapping of some elements rather than collapsing.
Edit2-
Request the answer givers that if they want to break up the snippet for convenience of their explanations, they should also put in their answer the full snippet or its modification besides the parts of snippet. Because divs do not act in isolation. The answer should have the header with position: absolute, its h1 and the margin-top applied to the h1 of the div below the header.
Please see this snippet -
div.header {
position: absolute;
left: 0%;
top: 0%;
width: 100%;
height: auto;
text-align: center;
color: #EE82EE;
background-color: #000000;
}
.submenu {
text-align: center;
width:100%;
margin:0;
margin-top: 72px;
color:black;
height: 100px;
background-color: red;
float: left;
padding:0px;
}
#media screen and (max-width: 766px){
.submenu {
float:none;
}
}
<div class="header">
<h1>HEADER </h1>
</div>
<div class="submenu">
<h1>MENU</h1>
</div>
Edit:
As I explained in my comments, the h1 in your header doesn't collapse because it uses position:absolute - which, as you can see below, is one of the fixes to prevent collapsing margins. The overlapping is only happening because your header is absolutely positioned, so it will appear on top of everything else in the page.
To summarise loosely, collapsing margins happen when vertical margins touch on block elements that have no separation between them (e.g. borders or padding), are not floated, not absolutely positioned, not fixed and have overflow:visible (the default value). There are some other cases but that covers the vast majority causes, including yours.
Answer
What you're seeing is the effect of collapsing margins.
The CSS spec says that when the vertical margins of two elements touch, the two margins will be combined to form a single margin.
This also occurs with parent/child elements when there is no separation between the first (or last) child and the parent - in this case the collapsed margin ends up outside the parent.
In your case, your h1 has a default margin from the browsers stylesheet. This is being collapsed into its parent's margin i.e. the submenu element by default because it is a block element.
Prevent margin collapsing: There are a number of ways to prevent a margin of the child from collapsing including:
float
position: absolute.
change the display to one of: “table-cell”, “table-caption”, or “inline-block".
add an overflow other than visible, e.g. overflow:auto
add a "separation" between the parent and child, e.g. a border or padding.
When you add the float to your child, this is one of the methods that prevent the margins from collapsing, so you still have the space from the margin appearing at the top of your h1 that contains the word "Menu".
See some examples:
.submenu {
text-align: center;
width:100%;
margin:0;
margin-top: 0px;
color:black;
height: 100px;
background-color: red;
float: none;
padding:0px;
}
.container { border:2px solid #ff0;}
.container:after {
content: "";
display: table;
clear: both;
}
h1{ margin:30px 0;}
.submenu.hasfloat {float: left;}
.submenu.hasoverflow {overflow: auto;}
<p>The top margin of this h1 is collapsed into the parent's margin. </p><p>The parent's top margin is 10px, and the h1 has a top margin of 30px, so when collapsed the parent now takes on the child's margin because it is larger - you can see the margin surrounded with the yellow border:</p>
<div class="container">
<div class="submenu">
<h1>Collapsed</h1>
</div>
</div>
<p>The top margin of this h1 isn't collapsing because the parent is <b>floated</b>:</p>
<div class="container">
<div class="submenu hasfloat">
<h1>Not collapsed</h1>
</div>
</div>
<p>The top margin of this h1 isn't collapsing because the parent has <b>overflow:auto</b> (i.e. any value other than visible):</p>
<div class="container">
<div class="submenu hasoverflow">
<h1>Not collapsed</h1>
</div>
</div>
Example: Showing that the issue still exists even if the header is not absolutely positioned.
div.header {
position: relative;
left: 0%;
top: 0%;
width: 100%;
height: auto;
text-align: center;
color: #EE82EE;
background-color: #000000;
}
.submenu {
text-align: center;
width:100%;
margin:0;
margin-top: 72px;
color:black;
height: 100px;
background-color: red;
float: left;
padding:0px;
}
#media screen and (max-width: 766px){
.submenu {
float:none;
}
}
<div class="header">
<h1>HEADER <small>- position:relative</small></h1>
</div>
<div class="submenu">
<h1>MENU <small>- top margin is still collapsing</small></h1>
</div>
References: Read more about collapsing margins from:
Mozilla.org: Mastering margin collapsing
W3.org CSS3 Specification
Sitepoint: Collapsing Margins
CSS Tricks:What You Should Know About Collapsing Margins
The position: absolute applied to the header makes the div FIXED while all other divs become relatively MOVABLE. So, to make the others also fixed, we give them some other properties like display:inline-block, float:left etc.
Also, need to give a margin-top to the div below the absolute div to offset the collapsing margin
Please see working code with these fixes applied and which has all the divs at https://codepen.io/anon/pen/QqRgRB
The snippet is as follows -
div.header {
position: absolute;
left: 0%;
top: 0%;
width: 100%;
height: auto;
text-align: center;
color: #EE82EE;
background-color: grey;
}
.menu {
text-align: center;
width:100%;
margin:0;
margin-top: 72px;
color:black;
height: 100px;
background-color: red;
float: left;
padding:0px;
display: inline-block;
}
.submenu {
text-align: center;
width:100%;
margin:0;
margin-top: 0px;
color:black;
height: 100px;
background-color: yellow;
display:inline-block;
padding:0px;
}
#media screen and (max-width: 766px){
.menu {
float:none;
}
}
body {
margin:0px;
}
<div class="header">
<h1>HEADER </h1>
</div>
<div class="menu">
<h1>MENU</h1>
</div>
<div class="submenu">
<h1>SUBMENU</h2>
</div>

Stack div under an absolute div?

So I currently have the following HTML/CSS:
<style type="text/css">
body {
background: #eeeeee;
}
.table {
display: table;
margin: 0px auto;
max-width: 400px;
position: relative;
}
.row {
display: table-row;
max-width: 400px;
}
.td1,
.td2 {
display: table-cell;
border: 2px #aaaaaa solid;
padding: 15px;
background: #ffffff;
font-size: 18px;
color: #333333;
}
.td2 {
border-top: none;
color: #777777;
position: absolute;
max-width: 400px;
right: 0px;
left: 0px;
}
.under_div {
position: relative;
}
</style>
<body>
<div class="table">
<div class="row">
<div class="td1">Some random text that changes and can change the height of this div/td</div>
</div>
<div class="row">
<div class="td2">Some random text that changes and can change the height of this div/td</div>
</div>
<div class="row">
<div class="under_div">
<p>Some random text that remains the same always
</div>
</div>
</div>
</body>
My problem is that the second td (td2) needs to be position: absolute. There is a reason why it is so, so therefore it just can't be a regular div, as that would make this much easier :)
So, as you can see the next in the under_div is occupying the same space as the td2div. What I would like is for that to right under the td2div. In principle I could just try to position it so that it fits right under. But as stated in text of the divs the text changes, and therefore the height will be random for both the td1 and td2 divs.
So is there a way where I can stack the under_div div just under the td2 div where it of course follows along according to whatever size the two other divs have, and not just stick around in one position ?
I have tried just making another table-div after the first one. But that doesn't seem to do anything either...
I think you need to rethink your design a little as I don't think it's possible to do this with an absolutely positioned element. You can accomplish what I believe you want using float and clear. An example jsfiddle is here.

Centered website layout with varying sized columns and responsive?

I'm looking to create a website (or at the very least a homepage) like Joules.com
I essentially want to create boxes side by side in varying sizes but want them to resize or move to a new line with the browser window resizing (responsive?). It's also necessary for them to be centered. I can get to the point where I have the divs side by side but they don't seem to be centered... Here's what I have so far. Any help would be greatly appreciated. I'm kind of nooby in this department but wanting to learn!
CSS
#container {
width: 100%;
margin: 0 auto;
overflow: hidden;
}
#Womens {
height: auto
width: 241px;
float: left;
margin: 0 auto;
text-align:center;
}
#Mens {
height: auto
margin: 0 auto;
width: 241px;
float: left;
text-align:center;
}
#Footwear {
height: auto
margin: 0 auto;
width: 241px;
float: left;
text-align:center;
}
#Accessories {
height: auto
margin: 0 auto;
width: 241px;
float: left;
text-align:center;
}
HTML
<body><center>
<div id="container">
<div id="Womens">Womens</div>
<div id="Mens">Mens</div>
<div id="Footwear">Footwear</div>
<div id="Accessories">Accessories</div>
</div>
First at all you don't need to use an ID for each element, since your CSS code is the same for everyone use a classname instead:
<div id="container">
<div class="column">Womens</div>
<div class="column">Mens</div>
<div class="column">Footwear</div>
<div class="column">Accessories</div>
</div>
Then don't use float because you can't center those elements, use inline-block:
#container {
font-size:0;
text-align:Center;
}
.column {
font-size:14px;
display:inline-block;
}
Check this Demo Fiddle
Your CSS could be much simpler by using a class (Don't Repeat Yourself ;) ).
If you put text-align: center; on the container instead the container itself and its child contents will be centered. If you want you could then override the setting for the separate columns, or just for their content.
You've also used fixed pixel values for the column width, so they can't really be "responsive." You can use percentage values there as well, but that can have some screwy side effects. Note that 4 columns even with auto margins still need to be < 100% or else they wrap oddly. They also might collapse or overlap at smaller sizes. You can set a min-width on the container or the columns to help prevent this, along with a margin-bottom to keep them separate if they do wrap.
Also, if you just use percentage width and inline-block, the columns will be aligned at the bottom. Using vertical-align: top; fixes that. You said initially you wanted different heights, but if you didn't you could set a min- or max-height & put something like overflow:scroll on the content.
#container {
width: 100%;
min-width: 320px;
margin: 0 auto;
overflow: hidden;
text-align:center;
}
.box {
margin: 0 auto;
margin-bottom: 10px;
width: 20%;
min-width: 90px;
padding: 1%;
vertical-align: top;
display: inline-block;
background-color: #678;
color: #fff;
}
.content {
background-color: #fff;
color: #333;
padding: 1em;
text-align: left;
}
<body>
<div id="container">
<div id="Womens" class="box">Womens
<div class="content">This is some left-aligned women's content about/for women. View the Code Snippet in fullscreen!</div>
</div>
<div id="Mens" class="box">Mens
<div class="content">This is some left-aligned men's content about/for men. If you resize the browser the columns will be responsive, but break after a certain point.</div>
</div>
<div id="Footwear" class="box">Footwear
<div class="content">This is some left-aligned footwear content about/for feet. Feet are weird.</div>
</div>
<div id="Accessories" class="box">Accessories
<div class="content">This is some left-aligned accessory content about stuff you men or women could potentially put on their feet, or whatever.</div>
</div>
</div>
</body>

Floated div has a margin that is breaking the flow

I have two divs: floated left and floated right. The margin on the right div is breaking the left div, making it appear lower on the page than it should be. I want both divs to touching the top.
HTML:
<div class="right_div">
This div is in the right place.
</div>
<div class="clear"> </div>
<div class="left_div">
This div should be at the top</div>
CSS:
.right_div {
float: right;
margin-right:20px;
margin-top: 20px;
font-weight: 600;
background-color:blue;
}
.left_div{
margin-left: 20px;
margin: 0 0 0 20px;
padding: 0;
background-color: tomato;
text-align: left;
max-width: 10em;
}
.clear {
clear:both;
}
Here is the JSFIDDLE: http://jsfiddle.net/eLSc8/
remove
<div class="clear"> </div>
try this
<div class="right_div">
This div is in the right place.
</div>
<div class="left_div">
remove the
<div class="clear"> </div>
and the red element will stay on top.
As a sidenote, empty markup placed for styling purpose only should be avoided. If you need to apply a float clearing somewhere you should use non-structural approach like easyclearing and modern variants (e.g. see the .clearfix class of html5 boilerplate)
try this
http://jsfiddle.net/eLSc8/1/
please remove this clearboth
<div class="clear"> </div>
As everyone is saying; you can lose the clearing div.
Then simply add a float left to your other div to align it.
Depending on your structure and how you want it positioned, you might need to contain them or add margin. check jsfiddle.net/RSy6F/2/
Is this the desired effect:
http://jsfiddle.net/eLSc8/4/ ?
HTML:
<div class="left_div">This div should be at the top</div>
<div class="right_div">This div is in the right place.</div>
CSS:
.right_div {
font-weight: 600;
background-color:blue;
position: absolute;
top: 20px;
right: 20px;
height: 2.2em;
}
.left_div {
position:absolute;
top: 20px;
left: 20px;
background-color: tomato;
height: 2.2em;
}

How to align the top lines of two DIVs?

I want the top lines of two DIVs (<div></div>) to be aligned horizontally, how to do it?
Steven,
In addition to T. Stone's suggestion to float both divs, a simple way to align two divs is to make both have the display: inline-block; CSS rule and give the lower div the vertical-align: top; CSS rule.
Take a look at this simple jsFiddle example to see how this works.
div {
display: inline-block;
}
div#tall {
height: 4em;
}
div#short {
height: 2em;
vertical-align: top;
}
In response to "is there another way to do it", sure you could use display: inline but you have a bunch of hacks to remember to get it to work in IE6/7. This way is generally better (but it all comes down to the individual circumstances)
<style type="text/css">
.keeper {
overflow: hidden; /* expand to contain floated children */
}
.keeper div {
width: 200px;
height: 30px;
float: left;
border-top: 1px solid red; /* so you can see the 'tops' */
}
</style>
<div class="keeper">
<div>
</div>
<div>
</div>
</div>
Float them in a container.
.parent div { float: left; width: 50%; }
<div class="parent">
<div>1</div>
<div>2</div>
</div>
Note: The sum of the width of the child divs can not be greater than 100% of the parent div, including margin and padding.
Alternative
If maintaining flow with the page isn't a requirement, and all that really matters is aligning, them, the divs can always be positioned absolutely.
.abs { position: absolute; top: 100px; width: 50px; }
.left { left: 0px; }
.right { left: 50px; }
<div class="abs left">1</div>
<div class="abs right">2</div>

Resources