I am trying to make a table with a "sticky" table header. I set the position to absolute and it works, but now the header overflows horizontally past the table borders and even covers the scrollbar. How can I make an element absolute but still visually contained by its parent element?
It's hard to accurately display my code because I'm trying to modify Kibana and there are many different files involved but here is my best attempt at a simplified example:
HTML:
<div>
<table>
<thead>
<tr class="headerRow">
<th>...</th>
...
</tr>
<tr class="headerRowInvisible">
<th>...</th>
...
</tr>
</thead>
<tbody>...</tbody>
</table>
</div>
CSS:
div {
z-index: auto;
flex: 1;
display: flex;
flex-direction: column;
height: 100%;
min-height: 26px;
position: relative;
}
table {
width: 100%;
max-width: 100%;
margin-bottom: 20px;
border-collapse: collapse;
border-spacing: 0;
}
.headerRow {
white-space: nowrap;
position: absolute;
background-color: white;
z-index: 50;
}
.headerRowInvisible {
white-space: nowrap;
visibility: hidden;
}
If you're wondering about the invisible <tr>, setting the position to absolute messed with the formatting of the rest of the table and overlapped with the top of it, so I created an invisible <tr> with normal positioning so that it would create space and provide correct column widths to the table body. The background and z-index is so that the sticky header will properly cover the body when you scroll down. Otherwise you get text on top of text and it looks jumbled.
Use top, right and left properties to adjust the placement of that absolutely positioned element, and use margin-top on the next non-absolutely positioned element below it to create some space in order to avoid overlapping.
The following table method properly centers the div and the size of the div matches that of the content:
<table>
<tbody>
<tr>
<td width='50%'></td>
<td>
<div>
<input type='text' name='linksearch' size='40'/>
<a href=''>Search</a>
</div>
</td>
<td width='50%'></td>
</tr>
</tbody>
</table>
What is the equivalent CSS using just div elements? I see a lot of answers like:
div.center {
margin-left: auto;
margin-right: auto;
}
but when using this method it is not clear to me how to make the width of the div grow or shrink to match the content of the div. I can specify an explicit width but even then, the content can overflow to the right and thus it is not really centered (you can see this clearly by setting the background-color of the div).
So is the table method is still superior or is there a way to do this using only CSS?
UPDATE:
As requested, here is an example that illustrates the problem:
http://jsfiddle.net/qn0txere/3/
The first "table method" works as expected. The second 'margin: 0 auto' method does not really work in that the div does not shrinkwrap around the content. The content overflows to the right.
I see what you mean, but there are ways around that, and using CSS for the style is far more beneficial in the long run as it's much easier to change later on etc,
To fix the problem of the content going outside of the div you can use the auto property for the width and height,
Like this:
div.center {
width: auto;
height: auto;
margin-left: auto;
margin-right: auto;
}
You may also wish to add min-width and min-height properties if needed to make it look more appealing if there isn't a great amount of content within the div (or max properties) :
min-width: 300px;
min-height: 500px;
max-width: 500px;
max-height: 600px;
You may also wish to add a ID or class to the specific div, so in this case you can more clearly write the CSS for just that specific div
You have to add a containing div (preferred) or add properties to the body. Since your markup was wrong anyways, I'll go for the preferred method by adding the FORM element:
<div class="center">
<form>
<input size="40" name="linksearch" type="text"/>
Search
</form>
</div>
Now, since I have my required elements, I can center things and make them work as I want because I have the chance to add positioning for all elements ( + proper markup):
.center {
text-align:center
}
form {
white-space: nowrap;
padding: 10px;
margin:0 auto;
width: auto;
background-color: #cc0;
display:inline-block
}
Really easy, huh? You can see an update to your fiddle so you can preview and play around
I made an image slider for my forum homepage but the content is comming out of the wrapper.
How can I make sure the content will always be 100% width of the wrapper?
HTML:
<div id="wrapper">
<table>
<tbody>
<tr>
<td>
<div class="rg-content">
//image slider code
</div>
</td>
</tr>
</tbody>
</table>
</div>
CSS:
#wrapper {
margin: 0 auto;
max-width: 980px;
width: 90%;
background: linear-gradient(#fefefe, #e7e7e7);
}
.rg-content {
width: 100%;
background: #101010;
}
Screenshot:
What's Going On
It looks like your #wrapper doesn't have overflow set to hidden. Personally I tend to stay away from tables and use either float'd block elements or inline-block elements. I recently built a slider using figure for the outside wrap, ul for the fixed width inner wrap, and lis for each item. I had to set the figure to overflow:hidden for it to hide everything that wasn't supposed to be visible. Try adding that.
Code
#wrapper {
overflow:hidden;
}
Just add
<table style="width:100%;">
http://jsfiddle.net/jzLN6/
EDIT:
according to your jsfinddle and your comments I made some modifications to get this result
http://jsfiddle.net/bB9tQ/4/embedded/result/
is not fully functional but maybe its a basic idea of what you want to do
so if you want the layout to be fluid you will have to do some changes
remove de px of your ul and change your display to inline-block because if you have
display: block
this will make your li elements to lose the normal flow on the page and you won't be able to use % to stretch the content
<ul style="width: 100%; display: inline-block; margin-left: ;">
after that you should use % on each li tag instead of px.
if this is an approach to what you need, please let me know to give you a better elaborated example
I have an <img> that I want to center in a <div>. All previous answers I've found here use some hack or require you to know the image's width, which varies in my case.
Horizontal centering with text-align: center on the parent is easy. I can't figure out how to vertically align.
jsFiddle example
FYI Facebook does this well using just HTML and CSS. So please no <table> or javascript hacks. It looks like they are using something with line-height to make their <img> vertically center.
Remember that vertical-align: middle; is not to useful on its own, you also need to set the line-height: line-height:400px;.
This is useful if you have no other text in your <div> (except maybe a single line).
Working example: http://jsfiddle.net/kobi/ZfMYy/5/
Add a rule in your css class:
{vertical-align:middle;}
html, body, #wrapper {
height:100%;
width: 100%;
margin: 0;
padding: 0;
border: 0;
}
#wrapper td {
vertical-align: middle;
text-align: center;
}
<html>
<body>
<table id="wrapper">
<tr>
<td><img src="logo.png" alt="" /></td>
</tr>
</table>
</body>
</html>
As #kobi mentioned in a comment, all you need to do is set a line-height on your containing div. No tables.
jsFiddle example of vertically centered image
I was wondering if there were any simple examples that did the following
* A right and a left fixed column with a fluid center.
With full height and width and a header and footer.
* A single left fixed column with a fluid content column 2.
With full height and width and a header and footer.
* A single right fixed column with a fluid content column.
With Full height and width and a header and footer.
I've tried some methods (such as the ones listed on listapart) but they seemed really complicated and they used a lot of divs, or they just didn't support padding.
Thanks in advance
Check this site out:
http://matthewjamestaylor.com/blog/perfect-stacked-columns.htm
Other layout examples from the above:
http://matthewjamestaylor.com/blog/perfect-2-column-left-menu.htm
http://matthewjamestaylor.com/blog/perfect-2-column-right-menu.htm
http://matthewjamestaylor.com/blog/perfect-3-column.htm
The examples you found in alistapart.com are as complicated as they need to be, and every serious example that you can find about those layouts supports padding. You will find (and already found) a lot of good examples about it in the internet, just spend some time trying to understand them and you will see that they are not so complicated, in the end.
Anyway, I have a good demo layout similar to the second you are looking for, here:
http://www.meiaweb.com/test/BMS_DM_NI/
Basically, the html is this:
<body>
<div id="head">
<h1>Title</h1>
</div>
<div id="main">
<div id="navigation">
<!-- navigation content -->
</div>
<div id="content">
<h2>Content Title</h2>
<p>
<!-- main content here -->
</p>
</div>
</div>
</body>
And the css is:
html {
overflow: auto;
height: 100%;
}
body {
margin: 0;
padding: 0;
font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
width: 100%;
height: 100%;
line-height: 1.5em;
}
#head {
height: 20px;
background-color: #666;
color: #AAA;
padding: 20px 20px;
}
#navigation {
width: 210px;
padding: 20px 20px;
background: #efefef;
border: none;
border-right: solid 1px #AAA;
float: left;
overflow: auto;
}
#content {
margin-left: 250px;
padding: 20px 20px;
}
I think it's simple enough, and it works in all modern browsers.
I know that it's badwrong to do, and I'm a semantic coder through-and-through (that wasn't meant to rhyme), but I still use a single layout table to do columns.
Why? It's interoperable and simple. It doesn't require ridiculous CSS hacks that just barely hold things together (seriously, floats are meant for typography, not layout). It displays identically in every browser in current use. It. Just. Works. It's a semantic hack, but sometimes you just gotta do what you gotta do.
However, there is light on the horizon. The table-* display values for CSS make equal-height columns trivial, though they can still violate source order (you still need your left-most column to be before your center column, even if it's a nav section and should come near the end of your page code). IE8, and all non-IE browsers, support these already.
CSS3 Grids and CSS3 Template Layout will both solve this issue properly, but they're still quite a bit away from being usable. A coder can dream, though, right?
You can also look at Layout Gala - 40 examples of different two and three percent and fizxed-sized column layouts.
I have reworked my sample template so you can see all three of your requested formats in action.
This is a CSS solution, no tables involved. I have set this up so the side columns are fixed width the header/footer are fixed height. Everything else is fluid.
With all modern browsers, excepting for IE7, the content is centered both vertically and horizontally. IE7 has issues with its box model. I believe IE8 have these resolved.
The center box does center vertically in IE7 because I nested a 1 cell table in the center div as a hack around IE7 box model problems. I know this is dumb and ugly but it was just to show it worked.
See it in action - Three Column Full Screen Layout
I am a bit surprised this answer did not garner a single vote or capture the bounty. It works, its simple, and it fulfills everything the OP asked for. Oh well.
The CSS
DIV { text-align: center }
#h0, #f0 { float: left; clear: both }
#h1, #f1 { height: 100px; float: none; width: 800px }
#l0 { float: left; clear: left; }
#c0, #r0 { float: left; clear: none }
#l1, #r1 { width: 150px }
#c1 { width: 500px }
#l1, #r1, #c1 { height: 350px }
#h0, #f0 { background-color: orange }
#l0 { background-color: red }
#r0 { background-color: blue }
#c0 { background-color: yellow }
#h1, #f1, #l1, #r1, #c1
{ display: table-cell; vertical-align: middle; }
The HTML
<div id="h0"><div id="h1">
header
</div></div>
<div id="l0"><div id="l1">
left column
</div></div>
<div id="c0"><div id="c1">
<img alt="dilbert (3K)" src="../gif/dilbert.gif" height="82" width="80" />
</div></div>
<div id="r0"><div id="r1">
right column
</div></div>
<div id="f0"><div id="f1">
footer
</div></div>
http://www.alistapart.com/articles/holygrail
That should be exactly what you need.
Take a look at Yahoo's YUI: Grids builder.
I found the Liquid two column layout at Floatutorial extremely helpful when setting up a full height two column layout - fixed left column with a stretchy right column, with a header and foot row to boot. In their example, they suggest the left column is used as navigation, but it could be anything.
With Floatutorial, not only do you get a sample HTML structure and CSS out of it, but when you're done, you understand why you have what you end up with.
I briefly tried the YUI: Grids builder as suggestd by #JohannesH, and had some small problems with it, but the worst problem is that it was so convoluted that I had no idea why it wasn't working, or why it was supposed to have done.
Edit: there's also a tutorial for a liquid three column layout (which I've not used), and a whole bunch of other tutorials that use floats.
In response to a message from the original poster, here's how I would do the first request with a <table> (the others are trivial modifications):
<style>
body {
height: 100%;
}
#container {
height: 100%;
width: 100%;
border-collapse: collapse;
}
#top, #left, #center, #right, #bottom {
border: 1px solid black;
text-align: center;
vertical-align: center;
}
#left, #right {
width: 200px;
}
#top, #bottom {
height: 200px;
}
</style>
<table id="container">
<tr>
<td colspan=3 id="top">header</td>
</tr>
<tr>
<td id="left">left</td>
<td id="center">center</td>
<td id="right">right</td>
</tr>
<tr>
<td colspan=3 id="bottom">footer</td>
</tr>
</table>
There is a pre-fabbed css grid system that is based on the Golden Rule, and implements all types of column formats quite readily. Check out 960 Grid System. You can accomplish your goals without the use of tables. The nice thing that by using a pure CSS solution you can alter your layout more rapidly.
There is also a jQuery fluid implementation that has a fluid layout that you may be interested in.
This should have all you need:
http://maxdesign.com.au/presentation/page_layouts/
And a more general solution to all your CSS problems:
http://www.blueprintcss.org/
you should check out Elastic CSS Framework:
http://elasticss.com/two-columns-based-layout/
Cheers.