I'm trying to accomplish something that I thought would be simple, but it seems that when it comes to CSS, you never know!
I have an image float to the left. Beside it, I have a title and under that title, but still besides the image, I want to display a table taking all the remaining width. In IE and Chrome, the table ends up under my image while in Firefox, it takes more that 100% (an horizontal scroll bar is displayed). Firefox gives a result closer to what I want, but I don't want the scrollbar.
Here some code that I tried to make work using w3school "try it" editor (http://www.w3schools.com/css/tryit.asp?filename=trycss_float)
<html>
<head>
<style type="text/css">
h1{
font-size:1em;
}
img
{
float:left;
}
.field{
width:100%
}
</style>
</head>
<body>
<img src="logocss.gif" width="95" height="84" />
<div class="content">
<h1>this is the title</h1>
<form>
<table width="100%">
<tr>
<td><input type="text" class="field"/></td>
</tr>
</table>
</form>
</div>
</body>
</html>
I know the structure is too complex for that simple form, but forms are automatically generated by a PHP script so I'd like to keep it that way.
Because you have a floated image taking horizontal space from the .content div is why you get the extended table. The .content div is not aware of the floated image width. You can offset this by placing a margin at least the width of the image on the .content div.
.content
{
margin-left: 95px;
}
fiddle
Try setting your <table> to display: block in the CSS and dropping the width="100%" attribute:
table {
display: block;
}
http://jsfiddle.net/ambiguous/dyxw7/
The above example includes a red border on the table so that you can see where it is, I also changed the image to a kitten to make sure it would show up.
The .content div is 100% of the page wide including the bit under the floated image so the input set at 100% is also going to be that wide, to make the .content div take up only the space that's left after the floating image you can add overflow: hidden to it, but then the input itself can use varying box models, so I would suggest using a width of 99% on it. If the content is not actually an input then maybe 100% will work for most elements ;)
e.g. x-browser-code
h1 {font-size:1em;}
table {border-collapse: collapse; width: 100%;}
table td {padding: 0;}
.content {overflow: hidden;}
form {padding: 0; margin: 0;}
img {float:left;}
.field {
width:99%;
margin: 0 auto;
}
I think you have to float your table along with your image and remove the width:100% on your table.
<div id="content">
<div id="side_bar" style="float:left;">image</div>
<div id="main_content" style="float:left;">table</div>
<div style="clear:left;"></div>
</div>
or the old way
<table>
<tr>
<td>image</td>
<td>table</td>
</tr>
</table>
Related
I have the following peculiar problem. Lets start with a code snippet:
...
<td>
<div class="scrollable">...</div>
...other cell content...
</td>
...
Now I want the table render as if the div.scrollable wouldn't take any horizontal space (i.e. the div.scrollable doesn't push on the right side of the table), but show the horizontal scrollbar (on the div.scrollable, not on the whole cell) if the div.scrollable is wider then the containing cell. Is that possible to do via CSS?
Thanks!
Using your basic example you would likely need a set width on the td and to use overflow and overflow-y. overflow-y is CSS3 only but you didn't specify IE8 and below.
EDIT sorry you also need display:block; on the td
td { display: block; width: 50px; }
.scrollable { overflow: scroll; overflow-y:hidden; }
UPDATE:
See the jsfiddle example, notice the 100% width on the table and the fixed layout.. thats to stop the example from just adding a horizontal scroll to the viewport and carrying on.
http://jsfiddle.net/MMeTe/4/
Credit goes to Pricey as his jsfiddle example answers the question, but to have the answer with the code here, I attach it bellow:
...
<style type="text/css>
.mytable {
table-layout: fixed;
}
.scrollable{
overlow-y: auto;
}
</style>
...
<table class="mytable">
<tr>
<td>
<div class="scrollable">...</div>
other content...
</td>
</tr>
</table>
i have a header, which takes the whole width of the screen. in my header i want to place 3 divs, which should be aligned next to each other. the div's on the side being fixed-width, and the middle should take the other space available. so i don't know the width of the header, and i don't know the width of the middle container.
right now i have this code:
html:
<div id="header">
<div id="menu-container">
menu goes here
</div>
<div id="logo-container">
logo goes here
</div>
<div id="music-player-container">
music player comes here
</div>
</div>
and css:
#header {
height: 200px;
margin: 0;
padding: 0;
border: 0;
}
#menu-container {
width: 400px;
height: inherit;
float: left;
}
#logo-container {
height: 100%;
background-image: url('../images/logo.png');
background-repeat: no-repeat;
background-position: center;
float: left;
width: auto;
}
#music-player-container {
width: 400px;
height: inherit;
float: left;
}
which should be working according to other problems with the float.... it doesn't
You can use floated divs with negative margins:
http://jsfiddle.net/cy5E7/1/
In your case:
http://jsfiddle.net/AjVHy/
Negative margins are better then just left/right float fixed divs. We don't get messed layout if user have very small window. Look at this bad example (resize browser window to small width): http://jsfiddle.net/surendraVsingh/qZLHb/1/ (thanks to #SVS). In normal float layout, all floated divs are on place only if parent container is wide enough.
Another disadvantage of standard float layout is when we want column layout but we don't know height of middle content, look like it can look
float layout, dynamic content height
negative margins layout, dynamic content height
Switch the order of your second and third divs then use this CSS.
#menu-container, #music-player-container {
float:left;
width: 400px;
}
#music-player-container {
float:right;
}
#logo-container {
margin:0 400px;
}
jsfiddle example
I'm not exactly sure of what you are planning to code up, but in my perspective, I see it like this: "You want to have 3 columns, column 1 being of a fixed with, column 2 a fluid width and column 3 yet again of fixed width."
What I fail to understand here is that, in the case of a really small width monitor (like a 1024x768 resolution, for instance), having a 400px column on both sides would leave you with just 224px of logo space. It would look un-natural.
Anyways, if you would still like to continue, I suggest you enclose all the three divs [menu-container, logo-container & music-player-container] inside another element called header (If you're using HTML5) or another div with any name you like (If you're using <= HTML 4.01) and then fix it's width to 100%; and a fixed height of 200px;.
Then let the menu-container, float: left; and the music-player-container float: right;. This will give space to the logo-container. Let the logo-container have a width: auto;. Having done this will give you a basic semi-fluid header layout, if I'm right.
Cheers, hope your question gets solved quick :)
I understand what you're trying to do, and I am sorry to say that I have yet to find a solution for this issue without using some ugly form of JavaScript/jQuery.
Essentially, the problem is that CSS does not have any properties (not even when fiddling with display properties) that will allow you to have two elements, one with fixed width and the other taking up the remainder of the space in the div. There are some options with float that can allow you to very closely simulate this, but I can tell you that they are unlikely to give you what you really want.
There is a resource out there, a project called Bootstrap, that you can install like any other jQuery plugin (or you can actually use it like a "CSS" plugin - you'll see what I mean - if you don't want the JavaScript), that will enable you to do what you want.
Here is the link: http://twitter.github.com/bootstrap/download.html
I strongly recommend that you review the documentation first to make sure you are aware of any caveats/limitations.
Good Luck!
EDIT: I like rogal's answer, but before using it you should bear in mind that doing so removes your ability to add a left border and makes it very difficult to apply background images to the div with the negative margin.
another option:
#header {
display: table;
height: 200px;
margin: 0;
padding: 0;
border: none;
}
#header > div {
display: table-cell;
height: inherit;
}
#menu-container, #music-player-container {
width: 400px;
}
#logo-container {
background-image: url('../images/logo.png');
background-repeat: no-repeat;
background-position: center;
}
HTH
You could of course use a table..
-hides-
Something like this inside the header div:
<table width=100%>
<tr>
<td width=200>
menu
</td>
<td>
logo
</td>
<td width=400>
music
</td>
</tr>
</table>
(too lazy for CSS atm)
Can't think of a very good way to do this. Not an ideal solution, but you could turn this into a table.
<table>
<tr>
<td>
<div></div>
</td>
<td>
<div></div>
</td>
<td>
<div></div>
</td>
</tr>
</table>
Then you can just set the dimensions of the div and the td that contains it to be the same.
How may I display two images on a website with elastic layout, side by side which will autoscale to 50% of parent containter?
I was playing with it last night but didnt went too far.
When I went with divs, they overlaped each other or second image was displayed underneath first.
When I went with table, table become wider than screen resulting in vertical scroll bar.
I dont know in advance what size image is, nor what resolution user is having, idealy I would set this up purely by css, without using javascript.
I had luck on other page with single image autoscaling to fit in container by setting max-width:90% but I can't apply this trick here. Funny thing is, it this scenario max-width is set according to window (parent element), while in examples above max-width is set according to width of image itself.
Sorry for my english, if something is not clear, please ask.
Thanks
I see what you're saying. I had a problem with them being just a little bit too wide, so I took a little off of the margin, since it wouldn't take a fraction in the percent sign. See if this will do the trick:
<html>
<head>
<style>
div {
width: 80%;
background: #acf;
}
div img {
width: 50%;
padding: 0;
margin: 0 -0.2em 0 0;
}
</style>
</head>
<body>
<div>
<img src='a.jpg' />
<img src='b.jpg' />
</div>
</body>
</html>
Edit: Or even better, if all you have are the images in the box, don't let it wrap at all:
<html>
<head>
<style>
div {
width: 80%;
background: #acf;
white-space: nowrap;
overflow: visible;
}
div img {
width: 50%;
padding: 0;
margin: 0;
}
</style>
</head>
<body>
<div>
<img src='a.jpg' /><img src='b.jpg' />
<!-- Don't put a space between the images. -->
</div>
</body>
</html>
Is there a way to have two columns, that match each other in height, without using table cells, fixed heights or Javascript?
Using a TABLE
<table>
<tr>
<td style="background:#F00;">
This is a column
</td>
<td style="background:#FF0;">
This is a column<br />
That isn't the same<br />
height at the other<br />
yet the background<br />
still works
</td>
</tr>
</table>
Using DIVs
<div style="float:left;background:#F00" >
This is a column
</div>
<div style="float:left;background:#FF0" >
This is a column<br />
That isn't the same<br />
height at the other<br />
yet the background<br />
still works
</div>
<div style="clear:both;" ></div>
The goal is to make both backgrounds extend the full height regardless of which side is taller.
Nesting one in the other wouldn't work because it doesn't guarantee both side are the correct height.
Unfortunately, the preview showed the working HTML, but the actual post stripped it out. You should be able to paste this into an HTML file and see what I mean.
http://www.xs4all.nl/~peterned/examples/csslayout1.html
this is the kind of thing you want, give them both a height of 100% (using this css trick) and they'll stretch out to the height of the containing div!
edit: forgot to mention, put them in a container div!
Edit:
<html>
<head>
<style>
html, body
{
margin: 0;
padding: 0;
height: 100%; /* needed for container min-height */
}
#container
{
background-color: #333333;
width: 500px;
height: auto !important; /* real browsers */
height: 100%; /* IE6: treaded as min-height*/
min-height: 100%; /* real browsers */
}
#colOne, #colTwo
{
width: 250px;
float: left;
height: auto !important; /* real browsers */
height: 100%; /* IE6: treaded as min-height*/
min-height: 100%; /* real browsers */
}
#colOne
{
background-color: #cccccc;
}
#colTwo
{
background-color: #f4f5f3;
}
</style>
</head>
<body>
<div id="container">
<div id="colOne">
this is something</div>
<div id="colTwo">
this is also something</div>
<div style="clear: both;">
</div>
</div>
</body>
</html>
Just because nobody's said this, a lot of times people just fake the existence of even columns, by having a background image which tiles itself all the way to the bottom of the outer container.
This gives the appearance that the content is in two equal columns, even though one ends before the other.
Use the Faux Column CSS technique to solve this problem.
Given the following:
<div class="contentSidebarPair">
<div class="sidebar"></div>
<div class="content"></div>
</div>
You can use the following styles:
/* sidebar.gif is simply a 200x1px image with the bgcolor of your sidebar.
#FFF is the bgcolor of your content */
div.contentSidebarPair {
background: #FFF url('sidebar.gif') repeat-y top left;
width: 800px;
margin: 0 auto; /* center */
zoom: 1; /* For IE */
}
/* IE6 will not parse this but it doesn't need to */
div.contentSidebarPair:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
div.sidebar {
float: left;
width: 200px;
}
div.content {
float: left;
width: 600px;
}
There! Simple and effective. Absolutely zero JavaScript involved. And if you want to create more complex layouts (liquid layouts), you can adapt this technique using background-position. A tutorial is available here.
display:inline-block
With a trick, it even works in IE:
<div><span>
col1
</span></div>
<div><span>
col2
</span></div>
div {display:inline;}
span {display:inline-block;}
Yes, it is possible - pure CSS and no hacks - equal height columns.
Check this this article - it is very well written.
It's straightforward if you are dealing with browsers which support CSS2.1 (IE8 and above, all other major browsers). If this is your markup:
<div>
This is a column
</div>
<div>
This is a column<br />
That isn't the same<br />
height at the other<br />
yet the background<br />
still works
</div>
This would be your CSS:
div { display: table-cell; }
If you need more than one row in the layout you will have to add some wrapper elements in there, but otherwise this works straight off.
Theres a simple way of achieving this with clever HTML and CSS.
First the HTML:
<div id="container">
<div id="col1">
this is column 1
</div>
<div id="col2">
this is column 2<br />
it is obviously longer than the first column <br />
YEP!
</div>
</div>
Please note the lack of clear:both unsemantic div.
Now the CSS:
#container { background:#f0f; overflow:hidden; width:400px; }
#col1, #col2 { float:left; width:50%; }
#col2 { background:#ff0; }
The overflow hidden in the container rule makes sure that the container expands to the size of the contained floated divs (and gets rid of the unsematic clearing div that everyone loves so much).
The background of the container applies to the first column. The background of the col2 div applies only to the second div. This is what gives us the illusion that both divs are always the same height.
Simple, semantic solution in 3 lines of CSS. Enjoy
EDIT: Please comment on reason to vote down, otherwise I have to guess why my answer is wrong. In this case I had forgot to add the width property to the container so that it plays nice with IE6/7. Please check the revised CSS above.
<div>
<span>left</span>
<span>right</span>
<!-- new line break, so no more content on that line -->
<table>
...
</table>
</div>
How can I position those spans (they can be changed to any element) so that depending on how big the table is (not defined anywhere, and shouldn't be) the spans are positioned just on top of the left side of the table and the right side of the table.
Example:
a b
table0
table1
table2
(where a is the left span, and b is the right span)
P.S. You can change anything bar inner table html.
<style type="text/css">
#wrapper, #top, #tableArea
{
width: 100%;
padding: 10px;
margin: 0px auto;
}
#top
{
padding: 0px;
}
#leftBox, #rightBox
{
margin: 0px;
float: left;
display: inline;
clear: none;
}
#rightBox
{
float: right;
}
</style>
<div id="wrapper">
<div id="top">
<div id="leftBox">A</div>
<div id="rightBox">b<</div>
</div>
<div id="tableArea">
<table> ... </table>
</div>
</div>
Doesn't place them relatively, nor
does Rob Allen's answer, they put them
at the far reaches of the browser not,
within the table width.
Well they are going to be bound by their container width and Rob's answer makes both the table and container width 100%.
The only solution I can think of off hand is to put in a row in your table with a single column (spanning all columns) and in that row have your floated DIVs.
I ran into similar problem and I have found a solution. It doesn't depend on the width of the table but it is a little trickier. It works in every browser including IE5.5, IE6 and newer.
<style>
.tablediv {
float:left; /* this is a must otherwise the div will take a full width of our page and this way it wraps only our content (so only the table) */
position:relative; /* we are setting this to start the trickie part */
padding-top:2.7em; /* we have to set the room for our spans, 2.7em is enough for two rows otherwise try to use something else; for one row e.g. 1.7em */
}
.leftspan {
position:absolute; /* seting this to our spans will start our behaviour */
top:0; /* we are setting the position where it will be placed inside the .tablediv */
left:0;
}
.rightspan {
position:absolute;
top:0;
right:0;
}
</style>
<div class="tablediv">
<span class="leftspan">Left text</span>
<span class="rightspan">Right text <br /> with row</span>
<table border="1">
<tr><td colspan="3">Header</td></tr>
<tr><td rowspan="2">Left content</td><td>Content</td><td rowspan="2">Right content</td></tr>
<tr><td>Bottom content</td></tr>
</table>
</div>
<!-- If you don't want to float this on the right side of the table than you must use the clear style -->
<p style="clear:both">
something that continues under our tablediv
</p>
If you can't use a float for some reason, than you can use an alternative .tablediv style which I found by a mistake. Just replace the float:left; to display:inline-block; This works in all modern browser but not in IE7 and below.
Now you get my point and I'm sure you find any other solutions. Just don't forget that the .tablediv will be as long as the inner content. So placing a paragraph into it will cause to stretch to a bigger size than our table.
if you have divs instead of span, try float:left for span a and float:right for span b
<div>
<div style="float:left">a</div><div style="float:right">b</div>
<br style="clear: both">
aaaaaaaaaaaaaaaaaaaaaaaaaaa<br />
aaaaaaaaaaaaaaaaaaaaaaaaaaa<br />
aaaaaaaaaaaaaaaaaaaaaaaaaaa<br />
</div>
Doesn't place them relatively, nor does Rob Allen's answer, they put them at the far reaches of the browser not, within the table width.
I can't think of anyway, except to set the width of the table to something. In my case I choose 100%, which stretches to the width of the rapper at 50em:
<style type="text/css">
#wrapper {
width: 1%;
min-width:50em;
padding: 10px;
}
#mainTable {
width:100%;
}
#leftBox {
float: left;
}
#rightBox {
float: right;
}
</style>
<div id="wrapper">
<div id="leftBox">A</div>
<div id="rightBox">b</div>
<br style="clear: both" />
some text some text some text some text some text <br />
some text some text some text some text some text <br />
some text some text some text some text some text
<table id="mainTable" border="1"><tr><td>test</td><td>test 2</td></tr></table>
</div>
#MattMitchell, you might have something there. And then just use fload: left and float right I assume?