Positioning three divs with css - html

I have three divs:
<div id="login" />
<div id="content" />
<div id="menu" />
How would I define the CSS styles (without touching the HTML) to have the menu-div as the left column, the login-div in the right column and the content-div also in the right column but below the login-div.
The width of every div is fixed, but the height isn't.

#menu {
position:absolute;
top:0;
left:0;
width:100px;
}
#content, #login {
margin-left:120px;
}
Why this way? The menu coming last in the markup makes it tough. You might also be able to float both content and login right, and added a clear:right to content, but I think this might be your best bet. Without seeing the bigger picture, it is hard to give a solution that will definitely work in your case.
EDIT: This seems to work as well:
#content, #login {
float:right;
clear:right
}
More thoughts: The absolute positioning won't work (or won't work well) if you want to have the columns in a centered layout. The float seems to work - as long as you can get any border-between-columns type requirements to pan out with the float solution, you might be better off choosing that. Then again, if the site is supposed to be left align, I think that the absolute method would work very well for your needs.

Floats away... not perfect. Chris's answer seems a better solution.
#login {
float: right;
width: 400px;
border: 1px solid #f00;
}
#content {
clear: right;
float: right;
width: 400px;
border: 1px solid #f00;
}
#menu {
float: left;
width: 400px;
border: 1px solid #f00;
}
<div id="login">Login</div>
<div id="content">Content</div>
<div id="menu">Menu</div>

Related

Block Formatting Contexts, Collapsing Margins and Floating Containers

In order to understand what does a block formatting context do, I'm trying to find out what's going on when a BFC is not created.
I took the following demo from Everything you Know about Clearfix is Wrong:
.wrapper {
width: 740px;
background: #cccccc;
}
.leftSidebar {
float: left;
width: 200px;
}
.rightSidebar {
float: right;
width: 200px;
}
.mainContent {
padding-right: 200px;
padding-left: 200px;
}
.floatMe {
float: left;
background: teal;
color: #fff;
}
<div class="wrapper">
<div class="leftSidebar">
<h2>Heading</h2>
<pre>.leftSidebar {
float:left;
width:200px;
}</pre>
</div>
<div class="rightSidebar">
<h2>Heading</h2>
<pre>.rightSidebar {
float:right;
width:200px;
}</pre>
</div>
<div class="mainContent">
<h2>Heading</h2>
<pre>.mainContent {
padding-right:200px;
padding-left:200px;
}</pre>
<div class="floatMe">
<pre>.floatMe {
float:left;
background:teal;
color:#fff;
}</pre>
</div>
</div>
</div>
According to that article(emphasis mine):
In modern browsers:
All elements belong to the same block formatting context so adjacent
margins collapse. The heading’s margin “sticks out” of the wrapper to
butt against the p. Unlike in IE, it is that margin (not the one on
the black box) that creates the gap above the wrapper.
I cannot understand what does "the same block formatting context" refers to. I want to know why such a weird layout is produced without a block formatting context.
I've tried to figure out the exact layout by adding * {border: 1px solid blue;} to CSS, but the overall layout changed greatly after this change: now it behaves as if wrapper is a block formatting context!
.wrapper {
width: 740px;
background: #cccccc;
}
.leftSidebar {
float: left;
width: 200px;
}
.rightSidebar {
float: right;
width: 200px;
}
.mainContent {
padding-right: 200px;
padding-left: 200px;
}
.floatMe {
float: left;
background: teal;
color: #fff;
}
* {
border: 1px solid blue;
}
<div class="wrapper">
<div class="leftSidebar">
<h2>Heading</h2>
<pre>.leftSidebar {
float:left;
width:200px;
}</pre>
</div>
<div class="rightSidebar">
<h2>Heading</h2>
<pre>.rightSidebar {
float:right;
width:200px;
}</pre>
</div>
<div class="mainContent">
<h2>Heading</h2>
<pre>.mainContent {
padding-right:200px;
padding-left:200px;
}</pre>
<div class="floatMe">
<pre>.floatMe {
float:left;
background:teal;
color:#fff;
}</pre>
</div>
</div>
</div>
Please tell me what's going on.
Good question, got me thinking a lot!
There are lot of concepts at play here, so I'll get to them one by one:
Buggy IE:
Whatever is mentioned in this old article about IE can be easily ignored if you do not have to design for IE7 or IE8 compatibility mode. This behavior is due to hasLayout property used internally by IE7.
See this MSDN doc for IE7:
What is "HasLayout" and why is it important?
There are several bugs in
Internet Explorer that can be worked around by forcing "a layout" (an
IE internal data structure) on an element.
Clearly this is a non-standard workaround and along with brings up a lot of inconsistencies. Read about this here too.
Block Formatting Context (BFC):
Excerpts from this MDN doc:
A block formatting context is a part of a visual CSS rendering of a
Web page. It is the region in which the layout of block boxes occurs
and in which floats interact with each other.
BFCs are very important for positioning and clearing of floated elements- floated elements affects only within the same BFCs. When you float an element, it is taken out of the flow and reinserted by "floating".
See the examples below:
The inside of wrapper is a BFC where you float one div to left and another to the right.
The floated elements are reinserted into the BFC while rendering around the element that is not floated.
As you have not cleared the floating in the BFC, the wrapper height will extend to the size of the element that is not floated.
body{
margin: 0;
}
*{
box-sizing: border-box;
}
.wrapper{
border: 1px solid;
}
.wrapper > * {
display: inline-block;
border: 1px solid red;
width: 33.33%;
height: 100px;
}
.left{
float: left;
}
.right{
float: right;
}
.center{
height: 50px;
}
<div class="wrapper">
<div class="left">Left</div>
<div class="center">Center</div>
<div class="right">Right</div>
</div>
See what happens when you clear the floating in the BFC- now the heights will behave normally in the wrapper BFC.
body{
margin: 0;
}
*{
box-sizing: border-box;
}
.wrapper{
border: 1px solid;
}
.wrapper > * {
display: inline-block;
border: 1px solid red;
width: 33.33%;
height: 100px;
}
.left{
float: left;
}
.right{
float: right;
}
.center{
height: 50px;
}
.wrapper:after{
content: '';
display: block;
clear: both;
}
<div class="wrapper">
<div class="left">Left</div>
<div class="center">Center</div>
<div class="right">Right</div>
</div>
Collapsing Margins:
Top and bottom margins of blocks are sometimes combined (collapsed)
into a single margin whose size is the largest of the margins combined
into it, a behavior known as margin collapsing.
Margins collapse for adjacent blocks, parent and first/last child and empty blocks. See more about margin collapsing in this MDN doc.
Also note that:
Margins of floating and absolutely positioned elements never collapse.
So what really happens here?
So now you will have understood about BFCs and also how floating containers work in first case (when you have no borders specified) - that's why floatMe stays out of its immediate mainContent wrapper and exactly why the height of wrapper and mainContent is as it looks there.
Layout and IE referred to are only in IE7 and is non-standard.
Everything else that happens is because of margin collapsing:
a. h2 and pre margins collapse (adjacent siblings)
b. mainContent shifts a little bit to the top to collapse with the margin on the body (Parent and first/last child)
c. As wrapper takes the height of mainContent, the wrapper height is also shifted upwards.
d. What happens when you apply borders is that the margin collapsing in (b) above is nullified! (see MDN doc above as to why)
Hope things are looking better now. Cheers!

Responsive method for making a div take up the remaining available space

I'm currently trying to create a responsive form with an text field and a button next to each other, where the text field takes up the maximum available space and the button just uses what it needs.
This tutorial is what I've used so far to achieve this and its worked perfectly.
My issue is that this isn't really a responsive solution as if you remove the float using a media query to stack the field and button on top of each other, the button stacks on top of the text field instead of the other way around.
Here's a flexbox example I quickly whipped up. This is exactly how I need it to function but in a way that will work on IE8+ please.
Thank you
-
EDIT:
The button is content managed so using calc will not work in this instance & could contain multiple words which cannot break onto two+ lines.
Using percentage widths do not take into account the text inside the button. The button only needs to be the width of the text & padding. With a percentage there will either be excessive spacing on the button or there's a chance that multiple words inside the button will break onto two lines, I really need to keep them on one line which is where the non-responsive solution in my question comes in really handy. Unfortunately I really need it to be responsive. The button will always stay the same width no matter what size the container is, just the textbox that needs to adjust.
Does anyone know a way of achieving this please Preferably >IE8 (so no flexbox unfortunately)
-
What I have so far
https://jsfiddle.net/ncpk6qp9/
.container {
width: 300px;
border: 1px solid;
}
.left {
width: auto;
background: red;
overflow: hidden;
}
.right {
width: auto;
background: blue;
float: right;
}
.textbox {
width: 100%;
}
#media only screen and (max-width: 300px) {
.right {
float: none;
}
}
<div class="container">
<div class="right">
<input type="submit" />
</div>
<div class="left">
<input type="text" class="textbox" />
</div>
</div>
You can use percentage as width and display: inline-block;
Also, make sure you use font-size: 0px on the wrapper to remove inline-block spaces.
.container {
width:600px;
height:200px;
border:2px solid yellow;
font-size: 0px;
}
.left {
width:70%;
height:200px;
background:red;
overflow:hidden;
display: inline-block;
}
.right {
height:200px;
width:30%;
background:blue;
display: inline-block;
}
JSFiddle link
I can not test in old IEs, but I think that setting the div to position: relative when you reset the float should work.
I have changed the media query to work on hover, it's easier to check
.container {
width: 300px;
border: 1px solid;
}
.left {
width: auto;
background: red;
overflow: hidden;
}
.right {
width: auto;
background: blue;
float: right;
}
.textbox {
width: 100%;
}
.container:hover .right {
float: none;
position: relative;
top: 20px;
}
<div class="container">
<div class="right">
<input type="submit" />
</div>
<div class="left">
<input type="text" class="textbox" />
</div>
</div>

Auto expand div's width

Take a look at this fiddle that I found, and resize the result window: http://jsfiddle.net/qPHgR/286/
Here's the css from the fiddle:
.left {
float: left;
}
.right {
background-color: #DDD;
overflow: hidden;
}
I want to achieve the same thing, but I want the right div to have a fixed width (300px) and the left div to expand/contract when the window is resized. I can not figure out how to fix it without changing the HTML order of left and right div in the code. I've experimentet with floats and other attirbutes but can't make it work.
Thanks for your help!
.container {
position: relative;
}
.left {
background-color: #DDD;
margin-right: 300px;
}
.right {
position: absolute;
right: 0;
top: 0;
width: 300px;
}
How about this:
http://jsfiddle.net/7DKX8/2
.left {
float: left;
background-color: #DDD; }
.right {
width: 300px;
overflow: hidden; }
Updated jsFiddle
The floats are important for keeping the two elements next to each other. I added 310 pixels of margin to the right of the left DIV (300 pixels for the right DIV, and 10 pixels as white space). I then used a negative margin-left to pull the right DIV over on top of that margin.
I also added overflow: hidden; on DIV.container to illustrate a simple float containment solution. This can be removed if unnecessary, but you may find it makes the remainder of your layout styling easier.
Is this sort of what you want? http://jsfiddle.net/3ZUas/
The text interferes, but is this what you were going for?
Main thing is float: right;
Check this:
HTML:
<div class="container">
<div class="left">
some text goes here which is just here to change
</div>
<div class="right">
some longer bunch of text to go here, it should stick to the right some longer bunch of text to go here, it should stick to the rightsome longer bunch of text to go here, it should stick to the rightsome longer bunch of text to go here, it should stick to the rightsome longer bunch of text to go here, it should stick to the rightsome longer bunch of text to go here, it should stick to the right
</div>
</div>
​CSS:
.left {
float: left;
margin-right: 300px;
border: 1px solid #000;
}
.right {
position: absolute;
right: 0;
width: 300px;
background-color: #DDD;
overflow: hidden;
}
​
Hope this works for you...!

Placing two divs one below another

I am having some problems with placing two divs one below another.
I tried out some solutions found in Stackoverflow like below.
But Nothing seems to be working.
Code:
#wrapper {
position: absolute;
}
#up {
position: absolute;
float: left;
}
#down {
position: absolute;
float: left;
clear: left;
}
<div id="wrapper">
<div id="up"></div>
<div id="down"></div>
</div>
Here's My Attempt,
Fiddle
Helps would be appreciated.
Remove the CSS. DIV tags are block elements and would naturally flow down the page. You are floating them which would cause them to be displayed side by side.
Especially remove the "float" attributes.
That's how DIV's work by default, just remove your css. See a working example here: jsfiddle
<div id="wrapper">
<div id="up"></div>
<div id="down"></div>
</div>​
I'm not sure if you want the outer div to be greater than the height of the page, but that's what this does:
#DivSlider
{
width:100%;
position:absolute;
height:170%;
background-color:green;
}
#DivHome
{
height:26%;
background-color:orange;
border:1px solid black; /* You were missing the 'px' here */
}
#DivSkills
{
height:25%;
background-color:white;
border:1px solid black;
}​

Converting to tableless layout

I'm currently using 1 table to align 2 main portions of the site. It's causing problems for me now, so I'd like to use pure CSS.
I have a 205px wide navbar column on the left. Occupying the rest of the space on the right, I'd like to have a container (So on the right side of the screen, taking up screen width - 200 pixels) This container would not have a fixed height, but I want its top to be aligned with the top of the navbar.
Here's a demo of what I currently have .
I would like the solution to be similar to that, but not use tables, and have the top of the container aligned with the top of the sidebar.
I've made several attempts at doing this (before I started using the table, and after) but none of them even remotely worked. I've come here as a last resort, so I hope that someone could help.
Fiddle
.container{height: 100%; border: 1px solid #0f0; display: table;}
#sidebar{
width:40%; height: 100%; display: table-cell; background: #ccc;
}
#sidebar2{
width:60%; height: 100%; display: table-cell; background: #f00;
}
body, html {
height:100%;
}
HTML
<div class="container">
<div id="sidebar">links and whatnot go here</div>
<div id="sidebar2">this is the container (but its top is not aligned with the sidebar as I would like)</div>
</div>
Note: table-cell property is supported by supports IE8+
EDIT:
If you can't use table-cell then you have to use some jquery to calculate height. Check this Fiddle
I would do something like this:
. HTML:
<div id="container">
<aside id="sidebar">Links and whatnot</aside>
<section id="content">Content and whatnot</section>
</div>
. CSS:
html, body {
width: 100%;
height: 100%;
}
div#container {
height: 100%;
}
aside#sidebar {
background-color: #f00;
width: 205px;
min-height: 100%;
float: left;
}
section#content {
background-color: #0f0;
min-height: 100%;
}
You can see it working in this fiddle.