I'm trying to accomplish a 3 column fluid layout with an additional span at the bottom that covers the last 2 columns. In addition, I need to use source ordering so that the middle column is actually the first column in the markup.
I have an example fiddle working in chrome/safari/firefox here: http://jsfiddle.net/66krg9cr/6/
<div class="container">
<div class="middle">
<div style="height: 400px;"></div>
</div>
<div class="left">
<div style="height: 600px;"></div>
</div>
<div class="right">
<div style="height: 200px;"></div>
</div>
<div class="bottom"></div>
</div>
* {
box-sizing: border-box;
}
.container {
max-width: 90%;
margin: auto;
overflow: hidden;
}
.middle {
width: 48.59114%;
float: left;
margin-left: 25.70443%; // push toward the middle
margin-right: 2.81771%;
background: #000;
}
.left {
background: #333;
margin-left: -77.11328%; // pull towards the left
width: 22.88672%;
float: left;
}
.right {
background: #666;
width: 22.88672%;
float: right;
height: 200px;
margin-bottom: -9999px; // equal height column trick
padding-bottom: 9999px;
}
.bottom {
background: #999;
width: 77.11328%; // width of the last two columns combined
float: right;
height: 200px;
}
Unfortunately, I can't get this working correctly with IE9. In that browser, the bottom 2 column span drops below the bottom of the first column instead of being beside it. It seems the problem is the source ordering. If I change the order in the HTML to match the visual layout, then IE behaves. It's like IE remembers the height of the first column before it's moved left, and lays out the bottom span according to that height.
I would move the HTML around and just solve the problem, but it's going through a rigorous accessibility/screen reader review, and i know I would get dinged for not having the main content at the top of the source code.
Also, content in these divs will be dynamic in production, so I can't rely on knowing the height of any one column.
Any help would be greatly appreciated.
Why not stray away from negative margins and break the whole thing up into wrappers like this:
HTML:
<div class="container">
<div class="container-main">
<div class="top">
<div></div>
<div></div>
</div>
<div class="bottom"></div>
</div>
<div class="container-left">
<div class="left"></div>
</div>
</div>
CSS:
* {
box-sizing: border-box;
}
.container {
position: relative;
width: 90%;
margin: auto;
overflow: hidden;
}
.container-main {
position: relative;
float: right;
width: 77%;
margin: 0;
min-height: 100%;
}
.container-left {
position: relative;
float: left;
width: 23%;
margin: 0;
min-height: 100%;
}
.container-main .top {
width: 100%;
min-height: 400px;
}
.container-main .top > div:first-child {
width: 70%;
float: left;
background: #000;
height: 400px;
}
.container-main .top > div:last-child {
background: #666;
width: 30%;
float: right;
height: 400px;
}
.container-main .bottom {
background: #999;
width: 100%;
height: 200px;
}
.container-left .left {
background: #333;
width: 100%;
height: 600px;
}
Your main content is still at the top. If you don't have to have everything in one wrapper then this may work, I can't test it in older IE versions though, but you can give it a try and let me know!
Here is a Fiddle of the above in action: http://jsfiddle.net/egxfnjzL/
...and just for fun, here is an exact copy of what you had: http://jsfiddle.net/whkqnnyg/
Related
Is there a way I can set the right hand panel to be say 200px and for the left panel to take up the rest of the space?
At the moment the right panel appears under the left panel.
Also, if I change the parent width, the left and right panels should appear within the parent and be sized accordingly.
#left {
background-color: #ff0000;
}
#right {
float: right;
width: 180px;
margin-left: 190px;
background-color: #00FF00;
}
<div>
<div id="left">left</div>
<div id="right">right</div>
</div>
You can use flexbox:
#container {
display: flex; /* establish flex container */
}
#left {
flex: 1; /* consume all available space */
background-color: #ff0000;
}
#right {
flex: 0 0 180px; /* don't grow, don't shrink, fixed at 180px width */
background-color: #00FF00;
}
<div id="container">
<div id="left">left</div>
<div id="right">right</div>
</div>
jsFiddle
Note that flexbox is supported by all major browsers, except IE 8 & 9. Some recent browser versions, such as Safari 8 and IE10, require vendor prefixes. For a quick way to add all the prefixes you need, use Autoprefixer. More details in this answer.
Is there a way I can set the right hand panel to be say 200px and for the left panel to take up the rest of the space?
Yes.
There's a variety of ways you can implement it. I have listed four options below. The first three will require the use of width: calc(100% - 200px) for the left panel. The last option using flexbox does not require it.
Using position: absolute:
*, :before, :after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.container {
position: relative;
width: 100%;
}
#left {
background-color: #ff0000;
position: absolute;
top: 0;
left: 0;
width: calc(100% - 200px);
}
#right {
width: 200px;
background-color: #00FF00;
position: absolute;
top: 0;
left: 0;
margin-left: calc(100% - 200px);
}
<div class='container'>
<div id="left">
left
</div>
<div id="right">
right
</div>
</div>
Using display: inline-block:
*, :before, :after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.container {
position: relative;
width: 100%;
}
#left {
background-color: #ff0000;
display: inline-block;
width: calc(100% - 200px);
}
#right {
width: 200px;
background-color: #00FF00;
display: inline-block;
}
<div class='container'>
<div id="left">
left
</div><!--
--><div id="right">
right
</div>
</div>
Using float:
*, :before, :after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.container {
position: relative;
width: 100%;
}
#left {
background-color: #ff0000;
float: left;
width: calc(100% - 200px);
}
#right {
width: 200px;
background-color: #00FF00;
float: right;
}
<div class='container'>
<div id="left">
left
</div>
<div id="right">
right
</div>
</div>
Using display: flex:
*, :before, :after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.container {
position: relative;
width: 100%;
display: flex;
}
#left {
background-color: #ff0000;
flex-grow: 1;
}
#right {
width: 200px;
background-color: #00FF00;
}
<div class='container'>
<div id="left">
left
</div>
<div id="right">
right
</div>
</div>
Swap DIVs around to change processing order:
<div>
<div id="right">
right
</div>
<div id="left">
left
</div>
</div>
<style>
#left {
background-color:#ff0000;
}
#right {
float: right;
width:180px;
margin-left: 190px;
background-color:#00FF00;
}
/style>
That kind of layouts can be easily addressed by using Flexbox, other option is to use calc, which browser support isn't too wide, but could help... you'll need to add:
#left {float: left; width: calc(100% - 200px);}
That's assuming your other element will be 200px per your question (but not your code), please remove the margin-left from the element #right to make this work.
Hope this helps.
If you want to check browser support for calc, take a look to http://caniuse.com/#search=calc
The Obective here: Get column 2(skyblue) and column3(salmon) to float inside it's wrapper(green). The first column(lightgreen) is floated to the left, the second column(skyblue) is float left, and the third column(salmon) is floated right. What am I doing wrong here? Why are they sitting underneath my wrapper? I tried clear fixes and expanding the wrapper and can't get these columns to sit inside the container. Suggestions?
Demo - http://codepen.io/Chris-Brennan/pen/pJORJY
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
#wrapperGreen {
margin: 0 auto;
width: 960px;
height: 700px;
background: green;
}
#mainContentLightgreen {
width: 520px;
height: 700px;
background: lightgreen;
}
#contentleftSkyblue {
width: 200px;
height: 600px;
background: skyblue;
float: left;
}
#contentrightSalmon {
width: 200px;
height: 600px;
background: salmon;
float: left;
}
#footer {
height: 100px;
background: black;
clear: both;
}
<div id="wrapperGreen">
<div id="mainContentLightgreen">
</div>
<div id="contentleftSkyblue">
</div>
<div id="contentrightSalmon">
</div>
<div id="footer">
</div>
</div>
I dont know if I've misunderstood but I think its the order in which you are writing them?
Does this solve your problem?
<div id ="wrapperGreen">
<div id="contentleftSkyblue">
</div>
<div id="contentrightSalmon">
</div>
<div id="mainContentLightgreen">
</div>
<div id="footer">
</div>
</div>
You don't set the float left in
#mainContentLightgreen{
width:520px;
height:700px;
background:lightgreen;
float: left;
}
look at this sample
Instead of float use display:inline-block; or display:table-row;
If CSS3 is an option and you are not to worried about compatibility you could use column-count.
Float is used literally for floating element's so that it break's the document flow.
Like for instance you wanted to float an image to the left and have text wrap around it.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.align {
display: inline-block;
vertical-align:top;
}
#wrapperGreen {
margin: 0 auto;
width: 960px;
height: 700px;
background: green;
}
#mainContentLightgreen {
width: 520px;
height: 700px;
background: lightgreen;
}
#contentleftSkyblue {
width: 200px;
height: 600px;
background: skyblue;
}
#contentrightSalmon {
width: 200px;
height: 600px;
background: salmon;
}
#footer {
height: 100px;
background: black;
clear: both;
}
<div id="wrapperGreen">
<div id="mainContentLightgreen" class="align">
</div>
<div id="contentleftSkyblue" class="align">
</div>
<div id="contentrightSalmon" class="align">
</div>
<div id="footer">
</div>
</div>
I got this to work, if I'm understanding you correctly by nesting the div's inside of one another. For example the salmon div inside the green wrapper
<div id ="wrapperGreen"><div id="contentrightSalmon"></div>
</div>
This question already has answers here:
Why doesn't the height of a container element increase if it contains floated elements?
(7 answers)
Closed 8 years ago.
In the following scenario I do not understand why the height of the elements wrapper and content are not set correctly even though they are set to height: auto, meaning that the 2 divs with the class wrap are not displayed inside the wrapper and content divs.
I recreated the problem in this JSfiddle:
http://jsfiddle.net/202oy3k8/
The As you can see the two orange divs are not displayed inside the wrapper divs, even though the wrapper height is set to auto. What is causing this problem and how can I fix it?
HTML CODE:
<div id="wrapper">
<div id="content">
<div id="top">
</div>
<div class="dash"></div>
<p id="header">Header</p>
<div class="wrap">
</div>
<div class="wrap">
</div>
</div>
</div
CSS CODE:
html, body {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
#wrapper {
background-color: black;
margin-top: 2%;
width: 100%;
height: auto;
}
#content {
background-color: green;
width: 1224px;
height: auto;
margin: auto;
text-align: center;
}
#top {
background-color: pink;
height: 400px;
width: 60%;
margin: auto;
}
.dash {
width: 80%;
margin: auto;
margin-bottom: 1%;
height: 2px;
background-color: black;
}
p#header {
margin: 0;
text-align: center;
}
.wrap {
background-color: orange;
margin: 1%;
float:left;
width: 48%;
height: 400px;
}
You have to add a clear property to clear left float you have applied to .wrap divs.
What are float and clear for?
If you look in a typical magazine you’ll see images illustrating the
articles, with the text flowing around them. The float property in CSS
was created to allow this style of layout on web pages. Floating an
image—or any other element for that matter—pushes it to one side and
lets the text flow on the other side. Clearing a floated element means
pushing it down, if necessary, to prevent it from appearing next to
the float. Although floating was intended for use with any elements,
designers most commmonly use it to achieve multi-column layouts
without having to abuse table markup.
html,
body {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
#wrapper {
background-color: black;
margin-top: 2%;
width: 100%;
height: auto;
}
#content {
background-color: green;
width: 400px;
height: auto;
margin: auto;
text-align: center;
}
#top {
background-color: pink;
height: 400px;
width: 60%;
margin: auto;
}
.dash {
width: 80%;
margin: auto;
margin-bottom: 1%;
height: 2px;
background-color: black;
}
p#header {
margin: 0;
text-align: center;
}
.wrap {
background-color: orange;
margin: 1%;
float: left;
width: 48%;
height: 400px;
}
.clear {
clear: left;
}
<div id="wrapper">
<div id="content">
<div id="top"></div>
<div class="dash"></div>
<p id="header">Header</p>
<div class="wrap"></div>
<div class="wrap"></div>
<div class="clear"></div>
</div>
</div
Reference: w3.org - Floats and clearing - CSS-Tricks - What is "Float"?
I am having trouble getting my basic layout to work. I am new at HTML and CSS. How can I attain a 3 column setup on my website to allow for proper placing of ads along the sides?
I currently have 2 floating sidebars left and right and one content area that is not floating but there seems to be an invisible margin between the content area and the side bars.
HTML
<div class="float-left left-ad-space">
<div class="filler"></div>
</div>
<div class="float-right right-ad-space">
<div class="filler"></div>
</div>
<div class="body-wrapper">
<div class="filler">
<div style="width: 100%; margin-left: auto; margin-right: auto;">
#RenderSection("Featured", false)
</div>
<div>
#RenderBody()
</div>
</div>
</div>
CSS
body {
width: 100%;
background-color: white;
height: 1200px;
}
.body-wrapper {
width: 900px;
height: 100%;
}
.left-ad-space {
height: 500px;
width: 160px;
}
.right-ad-space {
width: 160px;
height: 500px;
}
.float-left {
float: left;
}
.float-right {
float: right;
}
.filler {
width: 100%;
border-style: solid;
border-width: 3px;
border-color: blue;
height: 100%;
}
You need to center the middle column.
EXAMPLE HERE
.body-wrapper {
width:900px;
height:100%;
margin:0 auto;
}
Aside from that, your calculations are a bit off because of the borders.
You could use box-sizing:border-box in order to include the element's border within it's dimension calculations. Most people just apply this property to all elements:
* {
box-sizing: border-box;
-moz-box-sizing: border-box;
}
You would otherwise need to include this on the individual elements.
You can use this idea for your design. If you want more info look up html5 3 column layouts.
<div class="columns">
<div class="lcol"></div>
<div class="ccol"></div>
<div class="rcol"></div>
</div>
.colums { width:800px;} /*your wrappers width */
.lcol, .ccol, .rcol {
background: gray;
margin: 0 10px;
padding: 10px;
}
.lcol { /*left column*/
float: left;
width: 100px;
}
.ccol {/*center column*/
float: left;
width: 300px;
}
.rcol { /*right column*/
float: right;
width: 100px;
}
I got the outcome I wanted (http://jsfiddle.net/jcx3X/40/), but I'm just curious as to why this (http://jsfiddle.net/jcx3X/41/) doesn't work. Why must the div listed first in the HTML be the one to be floated?
It is because the html is what determines the order of the dom (document object model) elements. The element that is not floated will act differently depending on the order.
Maybe THIS FIDDLE will help you on your quest. I just happened to be doing something similar.
HTML
<header class="global-header">
header
</header>
<div class="container">
<div class="column sidebar">
aside content fixed width
</div>
<div class="column page">
main content flexible width
</div>
</div> <!-- .container -->
CSS
html, body {
height: 100%;
margin: 0;
padding: 0;
}
.global-header {
width: 100%;
float: left;
padding: 1rem;
}
.container {
width: 100%;
float: left;
height: 100%;
overflow: hidden;
}
.column {
min-height: 100%;
padding: 1rem;
}
.page {
float: none; /* just to be clear */
background: #C0FFEE;
width: auto;
overflow: hidden;
}
.sidebar {
position: relative;
width: 20rem;
float: right;
background-color: #f06;
color: rgba(255,255,255,.8);
}