I'm looking for a 3 column css layout, with 1 fixed section at the middle and 2 fluid sidebar around it:
http://www.uploadup.com/di-UEFI.png
middle has 250px width (for example) and sidebars have (at minimum) 150px width. if browser width was longer than 550px (250+300), sidebars should have a longer width. (and middle always is 250px)
What is the CSS can do it? with compatibility in all browsers.
note: i saw this page, but i don't know how to change it for my wish
You can try to use inline-blocks for it. They are used rather rarely, but sometimes they are pretty good for layouts.
So, look at this: http://jsfiddle.net/kizu/UUzE9/ — with inline-blocks you can create layouts with any number of fixed and fluid columns. The algorithm:
At first, you add the padding equal to the sum of all the fixed columns to the wrapper. In your case — 250px.
Then, you add min-width to the wrapper equal to the sum of all the fluid columns' min-width.
Then, you add white-space: nowrap to the wrapper, so the columns won't jump.
And then just add the all columns that you need.
If you need support for IE7 and lesser, there are some additional things to know except for common inline-block fix:
You must return white-space: normal to the inner child of a column, or the columns won't stay on one line.
There can appear a phantom scroll in IE, maybe there is a better way to remove it, but I just use overflow: hidden on some wrapper.
Enjoy :)
To make this work in IE6/7 without JavaScript, the easiest way to do this is with a table.
I know, I know. It's not that bad in this case, all considered.
See: http://jsfiddle.net/thirtydot/Q2Qxz/
Tested in IE6/7 + Chrome, and it will just work in all other modern browsers.
HTML:
<table id="container" cellspacing="0" cellpadding="0">
<tr>
<td id="left">fluid</td>
<td id="mid">fixed</td>
<td id="right">fluid</td>
</tr>
</table>
CSS:
html, body {
margin: 0;
padding: 0;
border: 0
}
#container {
border: 0;
table-layout: fixed;
width: 100%
}
#container td {
vertical-align: top
}
#mid {
width: 250px;
background: #ccc
}
#left {
background: #f0f
}
#right {
background: #f0f
}
If you don't use one of the ready templates out there,
You can start by three div floated left, the middle with width: 250px and the outside ones with
min-width: 150px
You might want to replace it with the <section> tag, just give it a display: block
Related
A JSFiddle of it: http://jsfiddle.net/24tL8mkq/3/
I want the red highlighting to continue all the way across the box.
Right now, it's set-up such that:
<div style='width: 500px; overflow: auto; border: 1px solid black; padding-top:-5px;'>
<pre id='pre_1'>
<!-- code box -->
</pre>
</div>
with the relevant css (this is the CSS that I want to extend across the entire div, through the overflow) being:
.bad {
background-color: palevioletred;
width: 100%;
}
I get that I can't use width: 100% as that'll only extend to the right most side of the overflow always, but I can't set a static width as I don't know what the size of the box could be.
I'd really prefer to keep this a HTML/CSS solution if possible just to make this as portable as possible.
Interesting problem. The following works for me in the latest Firefox, Chrome and IE11, though I'd consider this somewhat "experimental" - definitely should be further tested if you need to support a broader range of browsers.
http://jsfiddle.net/24tL8mkq/5/
pre {
display: table;
}
pre > div { display: flex; }
I wish I could tell you why this works, but I don't know. I wasn't able to find another combination that works, however. My guess: setting the pre to display: table makes it so the width will go wider than 100% (500px), as tables will do (when their children are wider than the table). Setting flex on the div children is filling the available space since all the children should be equal width.
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/
Please see this JSFIDDLE
td.rhead { width: 300px; }
Why doesn't the CSS width work?
<table>
<thead>
<tr>
<td class="rhead">need 300px</td>
<td colspan="7">Week #0</td>
<td colspan="7">Week #1</td>
<!-- etc..-->
</tr>
<tr>
<td class="rhead"></td>
<td>S</td><td>M</td><td>T</td><td>W</td><td>T</td><td>F</td><td>S</td>
<td>S</td><td>M</td><td>T</td><td>W</td><td>T</td><td>F</td><td>S</td>
<!-- etc... -->
</tr>
<thead>
</table>
Also, what are the effects of position:fixed, absolute etc have on td widths if any? I am looking for a reason more than a fix. I am hoping to understand how it works.
This may not be what you want to hear, but display: table-cell does not respect width and will be collapsed based on the width of the entire table. You can get around this easily just by having a display: block element inside of the table cell itself whose width you specify, e.g
<td><div style="width: 300px;">wide</div></td>
This shouldn't make much of a difference if the <table> itself is position: fixed or absolute because the position of the cells are all static relative to the table.
http://jsfiddle.net/ExplosionPIlls/Mkq8L/4/
EDIT: I can't take credit, but as the comments say you can just use min-width instead of width on the table cell instead.
You're better off using table-layout: fixed
Auto is the default value and with large tables can cause a bit of client side lag as the browser iterates through it to check all the sizes fit.
Fixed is far better and renders quicker to the page. The structure of the table is dependent on the tables overall width and the width of each of the columns.
Here it is applied to the original example: JSFIDDLE, You'll note that the remaining columns are crushed and overlapping their content. We can fix that with some more CSS (all I've had to do is add a class to the first TR):
table {
width: 100%;
table-layout: fixed;
}
.header-row > td {
width: 100px;
}
td.rhead {
width: 300px
}
Seen in action here: JSFIDDLE
The reason it doesn't work in the link your provided is because you are trying to display a 300px column PLUS 52 columns the span 7 columns each. Shrink the number of columns and it works. You can't fit that many on the screen.
If you want to force the columns to fit try setting:
body {min-width:4150px;}
see my jsfiddle: http://jsfiddle.net/Mkq8L/6/
#mike I can't comment yet.
The reason, is, because you did not specify the width of the table, and your whole bunch of td's are overflowing.
This for example, i've given the table a width of 5000px, which I thought would fit your requirements.
table{
width:5000px;
}
It is the exact same code you provided, which I merely added in the table width.
I believe what is happening, is because your TD's are way past the default table width. Which you could see, if you pull out about 45 of your td's in each tr, (i.e. the code you provided in your question, not jsfiddle) it works exactly fine
Try this it work.
<table>
<thead>
<tr>
<td width="300">need 300px</td>
Try to use
table {
table-layout: auto;
}
If you use Bootstrap, class table has table-layout: fixed; by default.
My crazy solution.)
$(document).ready(function() {
$("td").each(function(index) {
var htmlText = "<div style='width:300px;'>" + $(this).text() +"</div>";
$(this).html(htmlText);
});
});
Use table-layout property and the "fixed" value on your table.
table {
table-layout: fixed;
width: 300px; /* your desired width */
}
After setting up the entire width of the table, you can now setup the width in % of the td's.
td:nth-child(1), td:nth-child(2) {
width: 15%;
}
You can learn more about in on this link: http://www.w3schools.com/cssref/pr_tab_table-layout.asp
If table width is for example 100%, try using a percentage width on td such as 20%.
Wrap content from first cell in div e.g. like that:
HTML:
<td><div class="rhead">a little space</div></td>
CSS:
.rhead {
width: 300px;
}
Here is a jsfiddle.
You can also use:
.rhead {
width:300px;
}
but this will only with with some browsers, if I remember correctly IE8 does not allow this. Over all, It is safer to just put the width="" attribute in the <td> itself.
I've got this problem, I've placed a div within a div, I've positioned the "title" to be height 50, and then "navbar" below it, so I've put height 100% though the thing is, its not staying within the div, its actually straying away from and out of the div and making a scrollbar appear.
I would love "site" to hog the walls and then all the other div fit in that div.
<div id="site">
<div id="title">TitleBar</div>
<div id="navbar">NavBar</div>
<div id="frame">FrameBar</div>
</div>
body{
margin: 0;
}
#site{
position:absolute;
width: 100%;
height: 100%;
*border: 1px solid #333;
}
#title{
border: 1px solid #333;
height: 50;
}
#navbar{
border: 1px solid #c38a8a;
width: 200;
height: 100%;
}
I've found an image that shows something similar.
http://img176.imageshack.us/img176/4637/picture1zb1.png
that's because 100% height actually means "use the same height as the container".
But I didn't quite get all your requirements for this layout, if your navbar is a navigation bar, it should be designed in a way that allows scrollbars to appear when the content is too big.
But I think you're going for the wrong structure to accomplish this, is there any actual reason you want a wrapper div? I've created a fiddle on this, check if this is closer to what you wanted: http://jsfiddle.net/6g6HV/2/
This other one is yours, in case you wanna play with it: http://jsfiddle.net/yq8PS/3/
Edit: Adding the javascript solution to the answer http://jsfiddle.net/6g6HV/9
You can make divisions in HTML appear side by side to each other by adding a float property to the css.
#navbar{
border: 1px solid #c38a8a;
width: 200px;
height: 100%;
float: left;
}
Additionally, always add the 'px' unit after a size. Modern browsers assume you mean px, but older ones might not.
There isn't a good way to prevent the overlapping when you have a sidebar that is a set pixel width. To achieve the liquid width (or fluid width) style, you would have to add negative 200px margin on the left to the #frame (to counter sidebar). Then, add another divsion inside the #frame to do the styling for that portion. This is how I have achieved the look on my web site, and it's also the solution used in the previous default Drupal theme (Garland).
#frame{
margin-left: -200px;
}
IN this context, 100% for the Navbar doesn't mean the remaining height but 100% of the visible heigth of the parent; so if the parent has a height of 400px then Navbar will also have an height of 400px. If you add to this size the height of the title bar, you get a total value greater than the size of the parent; therefore the appearance of the scolling bar.
While there is usually no problem with the width to make it appears to fill the whole length of a screen, it's very difficult in HTML & CSS to do the same with the height as they have not been designed for this sort of thing; especially with an imbricated structure (div inside div).
Some people will use Javascript to get the size of the screen (browser) and compute the size of their objects accordingly but I don't know if you can do the same with a pure HTML/CSS solution; especially if you want to have your solution compatible accross many browsers.
For more info, take a look at http://www.tutwow.com/htmlcss/quick-tip-css-100-height/
This is the website I'm having problems with: http://bgflirt.com
I need the menu on the left to have a fixed width and the part with the user pictures should resize when the browser window is resized (width in percent). However, as you can see - the part where the content is refuses to align on the right of the menu, but is instead displayed below it. Can someone help me with this ?
For #content_wrap remove width:100% and float:left. This will make box to stretch to fill all available horizontal space.
You'll need to also clear floats in whatever way you prefer. E.g., add overflow: hidden; to #content_wrap.
This works for me in firebug.
BTW, since you use fixed-width graphics for header and footer (frame with those nice rounded corners), you can't really stretch them.
Try using something like this for your CSS:
.container {
position: relative;
}
.sidebar_wrap {
position: absolute;
top: 0;
left: 0;
width: 130px;
}
.content_wrap {
margin-left: 130px;
}
I believe that is much easier to work with than a float.
A couple of things.
First, get rid of the xhtml doctype and instead start using an html 4.01 strict doctype. xhtml, besides being on it's way out, has inconsistent rendering across a lot of browsers.
Second, this is MUCH easier to accomplish with a table. Just set the width of the table to 100% and the width of the first column to 130px. The layout engine will take care of sizing the other side. Incidentally, this will solve some of the other issues you're going to run into such as making both sides have the same height.
your #content_wrap div has a 100% width, like so it's impossible for it to float left when theres a menu with a 130px width...
You should make the menu's width in % if you really want to make the site resizable... something like
#sidebar_wrap{
width: 15%;
float: left;
}
#content_wrap{
width: 85%;
float: left;
}
note that the sum of the width can't be bigger than 100%, and you should take paddings and borders in consideration.