FireFox: TH as offset parent for absolute positioned box? - css

I have run into a problem with position:relative on th elements in FireFox.
In Chrome and IE the th element is a valid offset parent for absolute positioned elements.
<div class="relative">
<p>fill some spacing</p>
<table>
<tr>
<th>
Hello?
<div id="absolute">Is it me you're looking for</div>
</th>
</tr>
</table>
</div>
.relative {
position:relative;
border:1px solid green;
}
th {
position:relative;
border:1px solid red;
}
#absolute {
position:absolute;
top: 0;
left: 100px;
width: 200px;
border: 1px solid blue;
}
http://jsfiddle.net/ntQqL/2/
In FireFox the #absolute element is positioned at the very top of the .relative, in Chrome and IE it is positioned at the top of the th, like I expected.
Is this a well-known difference, or am I doing something wrong?

It probably has to do with the way the display and position properties are handled...
If you put a display:block on your th, it will work.
Christiaan answer also works.
But I guess the best way to fix this issue would be to put a relative positionned div inside your th.

It does seem to work when you put position:relative on the table instead of the th. Maybe that could be used as a workaround in your situation?

Related

Positioning top of element relative to table cell when position is absolute

Please go to my site here:
http://35.232.230.0:81/
You'll see a table of catalog items. Hover over one of the images. You should see the image enlarge.
You might also notice the image flickers a bit. This happens when you hover the mouse over the upper portion of the thumbnail.
The reason this is happening is because, as you'll notice, the top edge of the enlarged image is position around the middle of the thumbnail image. This means that when the image enlarges, the mouse is positioned just above the enlarged image. This means that as soon as you move the mouse, it detects that as a mouseout event, which causes the image to shrink again. But this in turn triggers the enlargement because the mouse is still hovering over the thumbnail image. This results is a cycle of enlarging and shrink which, when seen really fast, gives you the flicker.
So I'm wondering if there's a way to force the top of the enlarged image to be the same as the thumbnail image.
The hover event causes a css transition where the class being transitioned to sets the image's position to absolute:
img {
transition: width 0;
&:hover {
position: absolute;
z-index: 100;
width: 300px;
border: 1px solid black;
box-shadow: 5px 5px 10px grey;
transition: width .2s linear;
}
}
I would try to adjust the enlarge image's top property by setting it to 0, but with position: absolute, this just results in the image being positioned at the top left corner of the screen. I'm not sure how to calculate the position in CSS relative to its containing element (a td in a angular mat-table), so I'm a bit at a loss as to how to do this.
Any help would be much appreciated. Thanks.
First, for position: absolute to achieve your desired effect, you'd need to have positioned parent it can relate to (anything that is not position: static).
That means setting position: relative on the containing <td> should work. But alas, it doesn't. :( That is because relative position on table cells is undefined and most browser don't handle it very well. Bummer.
So, your best bet is to wrap your image with a <div> (or something similar) with position: relative set like in the following example.
table {
border-collapse: collapse;
}
table th,
table td {
padding: 5px;
}
table td {
border-top: 1px solid;
}
div {
height: 100px;
position: relative;
width: 100px;
}
img {
border: 1px solid transparent;
height: auto;
position: absolute;
transition: width .2s linear;
width: 100px;
z-index: 100;
}
img:hover {
border-color: #000;
box-shadow: 5px 5px 10px grey;
width: 400px;
z-index: 110;
}
<table>
<tr>
<th>Name</th>
<th>Image</th>
<th>Description</th>
</tr>
<tr>
<td>Name</td>
<td>
<div>
<img src="https://dummyimage.com/400x400/f48224/fff" alt>
</div>
</td>
<td>Description</td>
</tr>
<tr>
<td>Name</td>
<td>
<div>
<img src="https://dummyimage.com/400x400/f48224/fff" alt>
</div>
</td>
<td>Description</td>
</tr>
<tr>
<td>Name</td>
<td>
<div>
<img src="https://dummyimage.com/400x400/f48224/fff" alt>
</div>
</td>
<td>Description</td>
</tr>
</table>
Another solution might be to work with CSS transforms (scale), since those don't alter the element's document flow.

Why does my absolutely positioned table not fill its container div?

I have a table inside a div, and the table won't fill the container div. Why not?
HTML:
<div class="fill">
<table class="table">
...
</table>
</div>
CSS:
.fill {
position:relative;
width:100%;
height:100%;
}
.table {
position:absolute !important;
left:0 !important;
right:10px !important;
bottom:0 !important;
top:39px !important;
}
The table only fills a small portion of the container div. Why?
UPDATE:
Or, If I try the following, it doesn't work in Firefox, but it does in Chrome.
HTML:
<div class="fill">
<div class="wrap">
<table class="table">
...
</table>
</div>
</div>
CSS:
.fill {
position:relative;
width:100%;
height:100%;
}
.wrap {
position:absolute;
left:0;
right:0;
top:39px;
bottom:0;
}
.table {
position:relative;
height:100%;
width:100%;
}
This second version is closer to what I want (since it DOES work in Chrome).
In regards to your original question, this is the answer to your 'why not':
If the height of the containing block is not specified explicitly
(i.e., it depends on content height), and this element is not
absolutely positioned, the value computes to 'auto'.
Source: http://www.w3.org/TR/CSS2/visudet.html#the-height-property
Your 'fill' div is set to 100% height, but what is its parent element's height set to? And if its parent element's height is also a percentage, what is its parent's height set to, and so on?
Add borders to your updated example and you could see, the height of 'fill' is 0 as it has no parent with a specified height, and so the height of 'wrap' is also zero. Add a parent wrapper to wrap the whole example with a height of 500px or so and it works as expected in (at least) Firefox and Chrome.
CSS:
.fill {
position:relative;
width:100%;
height:100%;
border: 1px solid red;
}
.wrap {
position:absolute;
left:0;
right:0;
top:39px;
bottom:0;
border: 1px solid blue;
}
.table {
position:relative;
height:100%;
border: 1px solid green;
}
.parent {
height: 300px;
}
HTML:
<div class="parent">
<div class="fill">
<div class="wrap">
<table class="table">
<tr><td>...</td></tr>
</table>
</div>
</div>
</div>
Tables are special, they don't behave like other block elements. Normally, a table will be just wide enough to hold its contents, and no more. Setting a width of 100% for the table should force it to fill the space allotted for it.
On .table, put width=100%
You may have to set a width for the td as well.. Depending keeping your layout structured
Your parent div of the table has a width and height of 100% which is going to be whatever the parent element is. The table needs to not be position: absolute, and therefore no need to have top, left, right, bottom set.
table {
border: 1px solid blue;
width: 100%;
height: 100%;
margin: 0;
}
Here's my fiddle of what you wanted, minus the top and right offsetting you have.
http://jsfiddle.net/jaredwilli/5s4DD/
You can instead use margin to set the top and right but you then cannot use the 100% width, that will not work. You can use display:inline-block, while not having a 100% width but instead dynamically setting the width to be 10px less than the width of the fill div's width using javascript but that's another thing. Same goes for the top positioning. You could do some other things too, but there's a lot of playing with things that you would need to do.
Also, you can use table, no need for a class unless you have multiple tables in the page.
And remove all of the !important's from your CSS.
It's never necessary to use !important, just saying.

Div content alignment

I have a dynamically generated div.
I have to add a dynamically generated HTML table on it.
The problem is when I'm add the table, it display as left aligned.
But the div is center aligned for text contents.
Assuming you have your table as a fixed width element, you can set margin-left/right to auto to center a block element in it's container. (Fiddle here: http://jsfiddle.net/SWakJ/)
HTML
<div id="div1">
<table id="tab">
<tr>
<td>test</td>
</tr>
</table>
</div>
CSS
#tab {
border:solid 1px black;
width: 200px;
height: 100px;
margin:2px auto;
}
You may try to add some css to your outer div.
I actually wrote a similar answer here:
Position this div in the center of it's container?
Give your code or just go quick to your code and check this. Put a div above table and set text-align= center. or if your table is in any td then assign text-align:center.
Also you can put tag and put table between it.
If you want to just center the table column than also provide text-align:center
I dont know about your code but as per problem this could help you.
function makeTable() {
row=new Array();
cell=new Array();
row_num=12; //edit this value to suit
cell_num=12; //edit this value to suit
tab=document.createElement('table');
tab.setAttribute('id','newtable');
tbo=document.createElement('tbody');
for(c=0;c<row_num;c++){
row[c]=document.createElement('tr');
for(k=0;k<cell_num;k++) {
cell[k]=document.createElement('td');
cont=document.createTextNode((c+1)*(k+1))
cell[k].appendChild(cont);
row[c].appendChild(cell[k]);
}
tbo.appendChild(row[c]);
}
tab.appendChild(tbo);
document.getElementById('mytable').appendChild(tab);
}
the you can set allignment through CSS as below:
#newtable{
border:2px solid #999;
font-family:verdana,arial,helvetica,sans-serif;
font-size:18px;
margin:auto;
}
#newtable td{
width:50px;
line-height:50px;
border:1px solid #000;
text-align:center;
}
or see this link "http://www.webmasterworld.com/javascript/3614377.htm"
You can use like this
<div id="div1">
<table id="tab">
<tr>
<td>test</td>
</tr>
</table>
</div>
CSS
#div1
{
width:500px;
text-align:center;
}
#tab {
border:solid 1px black;
width: 200px;
height: 100px;
margin:2px auto;
}
#tab td
{
/* width: 200px;
text-align:center;*/
}
Running Demo Jsfiddle

td {position:relative; left} does not move the border

Please see the following example:
http://jsfiddle.net/6t6hq/7/
when I use td with position relative to move it,
it only move the content but not the border.
How can I move the border with the content?
<table>
<tr>
<td id="relativeTD">1</td>
<td>2</td>
</tr>
<tr>
<td>3</td>
<td>4</td>
</tr>
</table>
<div id="expected">expected</div>​
<style>
td{
border:1px solid #000;
min-width:100px;
}
#relativeTD{
position:relative;
left:60px;
}
#expected{
border:1px solid #000;
position:relative;
left:60px;
}​
</style>
TD is of display: table-cell;!
So you can't move it using relative positioning. Instead, create another <div> inside the <td> and give border and stuff.
Instead, give position: absolute for the td. It works! Also, you need to give position: relative to the table.
Fiddle: http://jsfiddle.net/6t6hq/9/
Else, you can use margin-left too to the td.
You cannot move a single td border you need to move the whole table
Demo
table {
margin-left: 60px;
}
Either what you can do is give your table border: 0;, place a div inside your td
give it some width, border and position: relative with left: 60px; and you are good to go

Align contents of DIV always on one line

I have the following :
HTML
<th class="sort">
<div>
<div class="sort"></div>Last Name
</div>
</th>
css:
table.tablesorter thead th.sort
{
padding:0;
}
table.tablesorter thead th div.sort
{
margin:0;
width:15px;
height:30px;
float:left;
background: url("/Content/images/admin/sort.png") no-repeat;
background-position: 0px center;
cursor:pointer;
}
table.tablesorter thead tr th.sort a
{
cursor:pointer;
color:inherit;
vertical-align:middle;
float: left;
padding-top: 7px;
}
I want to display inner and inside vertically aligned middle and always on ONE line so that when a browser window is resized (small) it will not break and will not more underneath inner (which is what is happening now).
thanks
use the "display inline" command...
<div style="display:inline;float left;">First name</div>
<div style="display:inline;float right;">Last name</div>
Its not clear to me what "inner" and "inside" youre referring to (you mught want to update and elaborate a bit, as well as post the complete markup for the table) but it sounds like you basically want everything in the th to be in one continuous line regardless of avialable space. You can turn off the text from wrapping with whitespace: nowrap;. However your content is going to overflow the th because thats how table cells work, so you need to set overflow: hidden on something that wraps the text. Unless yo need more than one elemment inside the cells you dont need the float.
The markup might look like this:
<thead>
<th><div class="clip sort">First Name</th>
<th><div class="clip sort">Last Name</th>
</thead>
Whith the css like so:
.clip {width: 100%; overflow: hidden; whitespace: nowrap;}
th {vertical-align: middle; height: 30px;}

Resources