I'm having a very hard time trying to come up with html/css for a layout to suite the following:
Where the left area is a static menu. The right area is dynamic content, generated using a call to ASP.Net's RenderBody method. You may not believe it, but I have been trying to figure this out for hours. I keep getting either the right section ending up underneath the left section taking 100% of the width or not displaying at all, with Chrome's object inspector saying its 0 pixels wide.
I feel like a complete idiot as this seems as if it should be easy as pie. Could I please get some help?
There's several ways to go about this. Here's one not particularly fancy but straight-up way to go about it:
<body>
<div id="menu">MENU</div>
<div id="content"> content <br /> content <br /> content </div>
</body>
CSS:
div { border: 2px solid black; } /* demo purposes */
#menu {
float: left;
width: 150px;
}
#content {
margin-left: 154px; /* menu width + (2 x menu.border-width) */
}
See this jsfiddle for a working sample.
This solution has the added benefit that your content region will take up exactly 100% of the remaining width of its parent:
<div class="parent">
<div class="content">blah...</div>
<div class="left-menu">blah...</div>
</div>
CSS:
.parent { padding-left:200px;width:100%; }
.content { position:relative;float:left;width:100%; }
.left-menu { position:relative;float:left;width:200px;right:200px;margin-left:-100%; }
Excellent tutorial on fluid layouts: http://www.alistapart.com/articles/holygrail
Works in IE7 and newer, Safari/Chrome/Opera/Firefox...
The best way to do this is by using the already considered safe to use box-sizing property.
Take a look at the tinkerbin -> http://tinkerbin.com/AcJjYk0r
It works as you want it to. Fixed width for the menu, percentage based width for the content area.
Then...
...if you want the background-colors to expand to the highest of the heights between the two boxes (remember, one times the menu can be higher than the content box, and vice-versa), then the only way to go about it (no javascript) is to use a background image and place it below the two boxes. With css3 gradients (safe to use too) it's pretty easy. Take a look:
http://tinkerbin.com/3ETH28Oq
Related
I have something like the below for an electronic cigarette site I am designing:
<div id="top">
//code
</div>
<div id="nav">
//code
</div>
<div id="container">
//code
</div>
<div id="bottom">
//code
</div>
I want to structure it in a way that areas are defined by <div> tags and not by the contents themselves. Strictly speaking, things in a specific <div> element should be organized like the below:
I've tried things like float and it just looks tremendously ugly and text doesn't wrap properly. My first guess would have been to use css column properties but it splits the page into 2 parts with the bottom and top <div> elements being arranged above one or the other but never both.
I apologize if this is such a trivial task, but while I'm a pretty good logic programmer, css is not my strongest suit and it's something I generally devise through trial-and-error rather than rote memory or function.
The general spacing (ie. widths of <div> elements) is something I can accomplish, but just positioning things is something I'm at a loss about.
Here is the HTML:
http://pastebin.com/xbSypPcn
Here is the CSS:
http://pastebin.com/mZnBHPP0
Here is an image of what it looks like:
http://imageshack.us/a/img706/5117/uzbn.png
Here is an image of what I'd like it to look like: (excuse poor MSPaint work)
http://imageshack.us/a/img571/9219/uxm1.png
Excuse the very ugly site. I'd like to get the .css down before I furnish it to make it more aesthetically pleasing.
You should use something like this to accomplish your style task:
#top {
display: block;
height: 200px;
}
#left {
display: block;
width: 300px;
height: 500px;
float: left;
}
#right {
display: block;
width: 700px;
height: 500px;
float: right;
}
#bottom {
display: block;
height: 200px;
}
Combining the display: block with the right float and height and width settings should do the trick. I haven't tested this but the concept should help you get going in the right direction.
Additionally, you can nest div tags to get the desired text effect if the float is throwing this off.
For instance:
You may want HTML that looks like:
<div id="right">
<div id="right_content">
Your text here
</div>
</div>
edit/addition:
Thanks for adding your code HTML and CSS with the images is great! Since you are using a "liquid layout" % vs. px values... but you are still using px for your padding. I wonder if you took the padding values all out of the #contianer and #nav css styles it might fix it for you. It appears that you are very close now. You just need to trim the nav and container a bit so they look the way you are expecting them to look.
If you are using FF as a browser there is a great tool called Firebug that you can use to "inspect" your document. It will show you the html and corresponding HTML for whatever you point to. This tool has "saved my life" on many occasions.
This is a question similar to many that have been asked before. However, with all the previous questions, the necessary widths are known. For me, the widths are unknown.
If I have two columns (primary, secondary), how would I use css such that as primary expands and contracts, secondary fills the remaining horizontal space. I would like to achieve something like the split pane effect, where the location of the split is dictated by the size of primary.
It is imperative to understand that I do not know how many pixels or how much width primary will take up, primary's size will increase and decrease.
It could be:
|----Primary----|----------------------------Secondary---------------------------|
Or:
|-----Primary------|----------------------------Secondary------------------------|
Or even:
|-------------------------Primary------------------------|-------Secondary-------|
How would I do this using CSS? Is it even possible to make an element provisionally "greedy"?
Hmmm, if you're not adverse to using it, you could apply the display:table-cell CSS property to the columns, then use width:100% on the latter one. The HTML structure would look like this:
<div class="split-pane">
<div>
Left content
</div>
<div>
Right content
</div>
</div>
And the CSS:
.split-pane > div {
display:table-cell;
}
.split-pane > div:first-child {
white-space:nowrap;
}
.split-pane > div:last-child {
width:100%;
}
Here's a JSFiddle demonstration to show you what this achieves. Note how as you add more text in a line on the left, it'll push the boundary to the right as needed. (The white-space:nowrap; is there so that the content on the left doesn't wrap on every single word.) Be advised that this CSS will not be interpreted properly on older versions of IE, if that's of concern.
If this isn't what you were looking for, let me know and I'll be happy to help further!
It is correct you can't do this with pixels, however there are other ways to define width. I think you may want to try using % rather than px in your css.
If the content of the 'sencondary' div doesn't matter, you can make some css like this:
#primary { position: absolute;
z-index: 1; }
#secondary { position: absolute;
width: 100%;
z-index: 0; }
If there is content that needs to be moved dynamically, you can move the secondary div easily with jQuery. Here's a jsfiddle with the code: http://jsfiddle.net/LZJZU/5/
I'm currently creating a website and I came across a strange thing: I have a content div that's 950 width and centered on the page. Inside that I have a header div, a menu div and some other content div. I would like the menu div and that other content div to be right next to each other so I thought about using float:left on both divs. However, when I use this float:left on the menu div, it's getting pushed to the right and I can't figure out why. I think some other element is pushing it to the right.
I'm using a custom Drupal theme, a subtheme of Zen to create the page by the way.
Here's the HTML I'm using to create the page (without the header):
<div id="root">
<div class="content">
<div class="left-menu">
<ul>
<li><p>Camera</p></li>
<li><p>Audio</p></li>
<li><p>Licht</p></li>
<li><p>Lenzen</p></li>
<li><p>Grip</p></li>
<li><p>Accessoires</p></li>
<li><p>Recorders</p></li>
<li><p>Transport</p></li>
<li><p>Edit suits</p></li>
<li><p>Crew</p></li>
</ul>
</div>
<div class="products-overview">
This is some other content that I want to the right of the menu.
</div>
</div>
And here are some CSS properties I've set on left-menu and products-overview:
.left-menu {
margin-top: 10px;
background-color: #BBB;
width: 150px;
float: left;
}
.products-overview {
background-color: #BBB;
float: left;
}
Could anyone please explain me why the left-menu is being pushed to the right?
Hmm, I believe this is a result of the normalize.css stylesheet you're using.
The problem stems actually from the .header element, which has a table within it. The normalizing stylesheet has a margin-bottom:1.5em applied to the table, which translates into a margin on the .header element (since it has no padding/border), which in turn sends the .left-menu to the right (since the margin causes there to be no space for it to fit on the left).
Adding to your current .header table definition can fix this, with a simple:
.header table{
margin-bottom: 0;
}
I hope this is what you were looking for! If not, let me know and I'll be happy to help further. Good luck!
I tried to replicate your problem. I did and found a solution that should work. Just set the products-overview class to float:none. See this fiddle. http://jsfiddle.net/shaansingh/yj4Uc/
In Mozilla Firefox it looks ok to me. From your code, I can only see that you need a width for the content div. and watch the dimensions, especially left/right padding and borders.
My problem is with the header. So I basically have 3 columns of divs. I want the middle one to have a constant width of 980px, and then I want the left of the header to extend to the end of the browser window with a blue background color. As for the right of the header, I want that to extend to the end of right side of the browser with a black background color. It kind off looks like this:
<------------------------------[blue][center header][black]---------------------------->
I've done my research and all I could find so far are two columns with a fixed left column with the right column filling up the rest of the space. I wonder how this can be applied to my problem?
Would it be like:
<div style="width:100%;">
<div style="display:table-cell; background-color:blue;"></div>
<div style="width: 980px;">my header</div>
<div style="display:table-cell; background-color:black;"></div>
</div>
Thank you!
A simple solution - basicaly using your exact stying, but putting another block in the central table-cell element, something like this span here:
<div class="wrapper">
<div class="left"></div>
<div class="center"><span>my header</span></div>
<div class="right"></div>
</div>
I moved all the inline style to a separate CSS block and used class selectors:
.wrapper {
display:table;
width:100%;
}
.left {
display:table-cell;
width:50%;
background-color:blue;
}
.right {
display:table-cell;
width:50%;
background-color:black;
}
.center {
display:table-cell;
}
.center span {
display:inline-block;
width:900px;
}
here is a jsfiddle
and here I made the center much narrower for a better illustration: jsfiddle
Hope this helps =)
Unfortunately there isn't a super smooth way of doing this that is also has wide cross compatibility support. There is a CSS spec for display called flex or flexbox which would do what you want beautifully and elegantly, but it has very limited support at the moment. Here is some resources on flexbox for your perusal...
http://css-tricks.com/old-flexbox-and-new-flexbox/
In the meantime, you can achieve the layout you want with some basic CSS jiggery-pokery that will get you what you want, but it requires absolute positioning your middle div.
Heres the JSFiddle: http://jsfiddle.net/CW5dW/
Here's the CSS:
.left {
width: 50%;
height: 300px;
float: left;
padding-right: 160px;
box-sizing: border-box;
background: red;
}
.right {
width: 50%;
height: 300px;
float: right;
padding-left: 160px;
box-sizing: border-box;
background: blue;
}
.middle {
position: absolute;
width: 300px;
height: 300px;
left: 50%;
padding: 10px;
margin-left: -150px;
box-sizing: border-box;
background: orange;
}
What is going on here you might ask?
Basically, we are taking the div with class middle and removing it from the flow of the document. This allows us to float our left div left, and our right div right, with widths of 50% in order to fluidly take up ALL space of the browser.
We then tell the middle div to take up 300px of space (in your case 980), and we tell it to go 50% of the total width of your browser from the left. This doesn't center it though, because its calculated from the left edge of your div. So we give it a negative margin space of half it's width, to sort of "move" that left edge to the center of the div.
Then, since we know the middle div has a width of 300px (in your case 980), we can then say that the left div should have some padding on its right edge greater than or equal to half the middle divs width, in my example that's 150px, and I added 10px more so text couldn't come right to the edge of the div, so 160px total. We do the same for the right div but for it's left side. This limits the content of those two divs from falling underneath our middle div.
This answer is not an "answer" as such - it's an extended comment to #Michael's post. I have, however, posted another answer - a jQuery solution.
Regarding #Michael's answer (which is a very tidy solution indeed) there is a tiny issue that if you remove your height declaration (which the OP undoubtedly will) then the backgrounds for the various columns become exposed - this method relies on the backgrounds all levelling out at their bottom edge in order to make the design coherent. If the OP's design doesn't have backgrounds behind the columns then this solution should be fine. If backgrounds are required (which they might be judging by the question wording) then it could be awkward. Two solutions to this...
a simple javascript that scans the page for column length, finds the longest, and matches all shorter ones to the maximum.
The other (and probably better) solution is to drop a background into your with the columns already on it (it only needs to be 1px high I guess) - just make sure the central white band is 980px wide and the side columns extend off a thousand or so pixels to accommodate even the largest of browsers
OK, here's my solution. This will present a "common or garden" three column fixed width layout to all users and then adjust it for users with javascript enabled (which, let's face it, is the vast majority of users). The benefits of this solution are that the layout will behave like any ordinary 3 solumn layout without the quirks you can experience from using more advanced CSS tweaks like absolute positioning and fixed heights.
Fiddle here... http://jsfiddle.net/vuary/
You should be able to see what's going on with the HTML and CSS... it's basic stuff. The jQuery is pretty straight forward too:
$(document).ready(function(){
// find the width of the browser window....
var docuWidth = $(window).width();
// find the width of the central column as set by the CSS...
// (you could hard code this as 980px if desired)
var centerWidth = $('#center').width();
// figure out how many pixels wide each side column should be...
sideColWidth = (docuWidth-centerWidth) / 2;
// then set the width of the side columns...
$('#left,#right').css({
width:sideColWidth+'px'
});
})
EDIT
Converted the jQuery to a function that is called when the document is ready, and again if the viewport is resized... just in case:
http://jsfiddle.net/aKeqf/
I have a layout with a menu DIV on the left. This is floated left with a fixed EM width. I then have a content DIV which has a left margin of more than the menu's width. So it sits nicely to the right of the menu and fills up the remaining space with both menu and content lined up perfectly.
However, in Internet Explorer 6, if the content gets too wide it falls down below the menu. which means you have loads of whitespace and can't actually see any of the content at all without scrolling.
Unfortunately I am not able to make changes to the content - this is a redesign of a site hosting 3rd party content, and changing that content is outside the scope of what I can do.
Also, there is a footer bar that must be underneath both the menu and the content.
I managed to almost get it to work by providing IE6 with a different layout using absolute positioning - unfortunately the footer looks rubbish and as IE6 is the 2nd most used browser on our site I can't really go with that.
I also tried messing around with overflows but ended up causing problems with random scrollbars appearing all over the place which wasn't any good either.
Does anyone know if there is a simple non-Javascript way of doing this that will work in IE6 as well as "proper" browsers? I'm currently thinking that it will have to be a table based layout.
Here's an example of the problem:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<style type="text/css">
.menu {
width: 14em;
float: left;
}
.content {
margin-left: 15em;
zoom: 1;
}
.footer {
clear: both;
}
/* styling to make the demo more obvious */
.menu {
background-color: #f99;
}
.content {
background-color: #9f9;
}
.footer {
background-color: #99f;
}
td {
border: 1px solid #000;
}
</style>
</head>
<body>
<div class="container">
<div class="menu">
<ul>
<li>menu item</li>
<li>menu item</li>
<li>menu item</li>
<li>menu item</li>
</ul>
</div>
<div class="content">
<h1>Main Content</h1>
<table>
<tr>
<td>this is a really</td>
<td>wide table which</td>
<td>I am using to push</td>
<td>the content down</td>
<td>need to keep going</td>
<td>so that it breaks</td>
<td>in ie6</td>
<td>but naturally</td>
<td>nothing else</td>
<td>sghskdhksdhfsdhffs</td>
<td>sghskdhksdhfsdhffs</td>
<td>sghskdhksdhfsdhffs</td>
<td>sghskdhksdhfsdhffs</td>
</tr>
</table>
</div>
</div>
<div class="footer">
<p>Copyright blah blah blah</p>
</div>
</body>
</html>
As you mentioned you already tried position absolute. But I'll tried the following and it might work for you. Here is the CSS:
.container {
position:relative;
}
.menu {
width: 14em;
position:absolute;
top: 0;
left: 0 !important;
left: -15em;
}
.content {
margin-left: 15em;
}
.footer {
}
Some explanation: The menu is positioned absolute, independent of the other content. However, IE puts the menu relative to the "content" div, and hides it behind the "content" div. The work around is to position it negatively, just as many em's to the left as the content div has "margin-left". But this should only done for IE, so therefor the "left 0 !important" is added (but before the negative left), which works because IE ignores "!important" while the other browers do acknowledge it and will use "left 0".
Update:
As Alohci notes a better way would be to use the "* html" hack, in that case the CSS for "menu" becomes:
.menu {
width: 14em;
position:absolute;
top: 0;
left: 0;
}
* html .menu {
left: -15em;
}
Why not use an established layout for eg http://layouts.ironmyers.com/
or you might want to investigate this css overflow
Have a look at this, does it help?
EDIT:
Try one of these fixes:
(you could use some conditional code like #Blake suggested)
overflow:scroll -- this makes sure your content can be seen at the cost of design (scrollbars are ugly)
overflow:hidden -- just cuts off any overflow. It means people can't read the content though.
.content {
margin-left: 15em;
zoom: 1;
overflow:scroll
/* overflow:hidden */ /* probably second best */
}
Try looking at this one How to prevent long words from breaking my div? is this your problem?
Use some conditional comments for IE6 to read and place in the necessary CSS to fix the width of the problematic divs like so:
<!--[if IE 6]>
IE 6 specific stuff goes here. You can load a specific stylesheet here, or just have inline css
<![endif]-->
You can read more on the conditional comments here.
Removing the zoom: 1;
makes it work just fine for me in IE6.
Too late, but usually i get flots fixed by adding or an absolute width (a number in pixels, points or any hard measure system instead on em, % and so) or sometimes to put a min-width property solves it, also, beware of padding and borders because of the boxmodel sum.
I have run into this so many times that I just try to stay away from floats entirely. That said, there are some things you can do to make them work, but you might have to settle for a fixed with layout and/or some IE6 specific fixes. Here are some things you can try:
This may sound like heresy but
tables are not wrong for layout,
they're just not cool.
Try setting the 'container' div with
a fixed width and auto margins.
If that doesn't work, try a fixed
width 'content' div with your fixed
width 'container' div.
THanks for the position:absolute idea. This is similar to one solution I almost went with.
The problem here is that the menu will overlay the footer if the menu is longer than the content (and it quite often is). I could try to add an arbitrary height to the content to try to force a minimum height, but I won't really know how big the menu will be. There's the potential for quite a lot going down the side panel in that area.
I presume there's no way to force the relative positioned container to grow in response to the absolute positioned content, is there? Even if it's an IE6 hack, as I can use the float method for other browsers.
(Again, sorry for not posting this as a comment but I don't get that as an option)