Div in table rowspan not using full height - css

I've got a pretty regular HTML <table> with one cell that spans multiple rows via rowspan. Inside of this cell I've got a <div> that I want to occupy the entire height of the cell but for the life of me I can't seem to figure it out. It seems similar to this post which mentions this Chrome bug but also seems so simple that maybe I'm just not thinking clearly.
Here's a stripped down version of my HTML:
<table>
<tr>
<td class="a" rowspan="2"><div>A</div></td>
<td class="b"><div>B</div></td>
</tr>
<tr>
<td class="c"><div>C</div></td>
</tr>
</table>
And CSS:
td
{
vertical-align: top;
}
td.a div
{
background-color: #f00;
height: 100%;
}
And a JSFiddle. And here's what I'm getting and what I'm trying to get:
What's really weird is if I use Chrome's inspector to change the <div> to display: inline-block and then set it back to display: block it actually looks pretty much exactly how I want it to.
(And no, switching away from a table isn't an option for this project, there's other code not shown that requires that.)

Option 1
Simply add overflow:auto; to your div CSS
Demo Fiddle
td
{
vertical-align: top;
}
td.a div
{
background-color: #f00;
height: 100%;overflow:auto;
}
Option 2
Alternatively you'll need to define the height of your table in order for the child to be able to calculate what its 100% is 100% of.
Option 3
The only other way would be to set position:relative on the td elements then position:absolute for the child div

Related

Make tds scrollable but leave th where it is?

Let's say this is the table:
<table>
<tbody>
<tr>
<th>something goes here</th>
<td>dkjfkldfjlfjs</td>
<td>dkjfkldfjlfjs 4234324</td>
<td>dkjfkldfjlfjfdgfdggs</td>
</tr>
</tbody>
</table>
Is it somehow possible to only scroll the tds from from left to right but leave the th where it is? Like when you fix a column in Excel where only the first column (the th) is frozen and the rest (all tds) scrolls at once.
Yes. You can, just apply overflow-x:scroll; with a display:inline-block; to achieve what you are looking for.
WORKING DEMO
The CSS:
td {
display: inline-block;
overflow-x: scroll;
}
Hope this helps.
Fiddle demo : Demo
When apply scroll to tbody, it may collapse table design. you have to manually apply width on header.
Adding scroll div block, below css is enough
min-height:200px;
overflow:auto;
For more details please check this blog post

:before pseudo-element causes gap in border

I have this piece of HTML that I want to style.
The html is a table (and actual table), which I want to give a border.
The element also had a :before pseudo-element, which I use to put a small triangle in the top corner.
The JSFiddle is here.
I hope it makes sense. I stripped down the markup and the CSS as much as possible, because it's actually a small part of a big site.
http://jsfiddle.net/GolezTrol/28yDb/2/
Now the problem is that the combination of having 2 columns, having border-collapse: collapse; on the table and the :before pseudo element, cause the top border of the element to partially disappear. It's only there for the length of the first column.
You would assume that it is the pseudo element that is on top of the border, but this element is very small, and as far as I can tell, this could not be the problem. I added visibility: hidden; to the pseudo element to be sure, and I can tell that the triangle is gone, but the border is still incomplete.
Unfortunately I cannot change the markup, since this is outputted by MediaWiki, but I do have full control over the CSS.
The HTML:
<div id="globalWrapper">
<div id="column-content">
<div class="thumb tright">
<table class="infobox vcard" style="">
<tbody>
<tr>
<th colspan="2" class="fn org" style=""> Example text</th>
</tr>
<tr>
<th>Row head</th>
<td>Content</td>
</tr>
The CSS:
/* Generic table styling */
table {
border-collapse: collapse;
/*border-spacing: 0;*/ }
/* The box */
.thumb.tright table.infobox.vcard {
border: 3px solid #fae104;
position: relative;
}
/* Triangle */
.thumb.tright table.infobox.vcard:before {
content: "";
position: absolute;
width: 0;
height: 1px;
border-top: 5px solid transparent;
top: -7px;
border-left: 10px solid #555;
visibility: hidden;
right: -1px; }
I already found out that it works when I remove border-collapse: collapse;, but I'm not sure that is a proper solution, and even if it is, I would really like an explanation of what is going on.
Btw. I got this problem both in Chrome 29 and in Internet Explorer 10. Haven't tested other browsers.
Update
Instead of using -or not using- 'border-collapse' to fix the problem, I found out that this also works:
.thumb.tright table.infobox.vcard tbody {
display: block;
}
So the table itself is still a table, the pseudo element is still on the table, as is the border, positioning etc. The tbody, which was unstyled before, is now a block and the problem is solved in both browsers. I found this by trial and error, and still wouldn't know the reason behind it.
Updated fiddle: http://jsfiddle.net/GolezTrol/28yDb/9/
Being a newbie to StackOverflow and jsFiddle I updated the Fiddle with that I think is the solution. I didn't change the CSS except for moving the pseudo class from the table itself to the table header, and changing it into :after. Works for me in Firefox and Chrome!
/* Triangle */
.thumb.tright table.infobox.vcard th:after { }
Border-collapse: seperate is not supported in IE8 but I think this will be.
edit: nevermind ;)
It is a problem only occur on Webkit browsers I think. It can be considered a "browser bug" imo.
th should be inside thead, not tbody:
<thead>
<tr>
<th colspan="2" class="fn org" style=""> Example text</th>
</tr>
</thead>
<tbody>
<tr>
<th>Row head</th>
<td>Content</td>
</tr>
<tbody>
And I think this is the correct solution. You are putting an element where it is not advised to be, so it should be normal for a problem to occur.
Edit: as thirtydot pointed out, changing the th to td doesn't change the result. It only work when I moved the th to the thead section. At this point I am at a loss, I can't find a way to solve this.
But at least I think I can provide my speculation on the cause of this problem:
:before create a pseudo element inside the target element. What kind of element is unknown to me, but I suspect that the browser create a td. If that is true, then after rendering your html should look like this:
<table>
<td></td> /*the pseudo element*/
<tbody>
<tr>
<th colspan="2" class="fn org" style=""> Example text</th>
</tr>
<tr>
<th>Row head</th>
<td>Content</td>
</tr>
<tbody>
</table>
Needless to say this look weird. And if you try the above html out you can see the result is similar to your problem. border-collapse:collapse will merge 2 borders together where there are 2 cells next to each other, or a cell is next to the table's border. So I suspect in this case, the pseudo element - which doesn't have appropriate colspan - last only 1 column, the rest of that row is empty: nothing's there. This is where I think caused the bug: because there's no cells next to the table border there, no border is created at all.
The real reason may be a little bit more complicated ("why doesn't the bug occur when I put in a thead?"), but I think my answer is not too far off the mark. :)
The only reasonable explanation I can think of is pseudo-element :before not being compatible with the display: table of the table in collapsed mode. That is why border-collapse: separate; solves the problem. Suddenly, the browser can display the top border not caring about the pseudo element.
If you look closely, you can clearly see that the missing part of the border is the width of the second column. If you change it to after pseudo element, the border is missing in the bottom-right corner, again due to the fact that the borders of the table and the pseudo-element are collapsed.
If you change the border-bottom of th to be 3px solid red in collapsed mode, the th overpowers the table and the border is red. I presume, the power of after and before follow the same rule. It would be nice if someone who knows the specs better came to answer that.
Thinking this way, I do not believe there can be any other solution than:
using separate borders
putting the pseudo element on the parent div
What I inspected is that the pseudo element is actually rendered as block and can be change to table and list-item. However, none of these change the behaviour.
Very random stuff that is actually compliant with Av Avt's answer about where the pseudo element is rendered in regards of the DOM.
If I append the :beofre like this, the border stays:
.thumb.tright table.infobox.vcard tr:before
Obviously, it creates as many new pseudo element as there are rows.

how do you center table using css

I have a table in my html that I would like to center on my page. I have the following code. I is perfectly find in ie but not in chrome. Am I doing something wrong?
<table align="center">
<tr>
<td>
<div class="zoom_controls"> </div>
</td>
</tr>
</table>
The align="center" syntax was deprecated a long time ago. Add margin:0 auto to your table:
table {
margin:0 auto;
}
jsFiddle example (border added for visibility)
Give the table a fixed width, if possible.
Give the table a top- and bottom-margin of 0 (or other if you want to) and a left- and right-margin of auto.
This works with every kind of element with a known width.
You can also use a variable width (em / %).
EDIT: seems like other were typing the same solution as me.
For me what worked is:
margin: auto;
display: inline-block;
Tables

CSS Positioning Absolute within table cells not working in Firefox

I cannot figure out this positioning problem in Firefox. It doesn't seem to follow the absolute positioning rule. Is there something I'm doing that shouldn't be done, but some browesers handle it and some don't?
JS Fiddle:
Original - http://jsfiddle.net/g9qzh/
Updated - http://jsfiddle.net/g9qzh/2/
Works in IE, Chrome, Safari, Opera
Here's the actual code. Let me know if I'm not following some kind of standard I don't know about.
HTML:
<table>
<tr>
<td>
<div id="three">Three</div>
<div id="two">Two</div>
</td>
<tr>
<tr>
<td>
<div id="three">Three</div>
<div id="two">Two</div>
</td>
<tr>
</table>
CSS:
#two {
position: absolute;
top: 0;
}
td {
position: relative;
}
​My only clue is that there is some other value that I should assign to td that would cause it to work. Some other stackoverflow questions have mentioned Firefox misbehaving with this, but I haven't been able to find an answer. I tried assigning both top and left values of zero, but FF won't budge.
​
Change ID's to classes and also displaying it as blocks fixes it:
http://jsfiddle.net/GchWZ/
It is better and more "proper" to user an inner div though as quoted from this stack overflow post: Does Firefox support position: relative on table elements?
<td>
<div style="position:relative">
This will be positioned normally
<div style="position:absolute; top:5px; left:5px;">
This will be positioned at 5,5 relative to the cell
</div>
</div>
</td>
You are using IDs
IDs are unique. Use Classes if you want to reuse a style assignment.
The problem comes from how FF renders tables. If you set your TDs to display:inline-block; it should display correctly.
Try this:
<tr>
<td>
<div id="wrapper">
<div id="three">Three</div>
<div id="two">Two</div>
</div>
</td>
</tr>
<tr>
<td>
<div id="wrapper">
<div id="three">Three</div>
<div id="two">Two</div>
</div>
</td>
</tr>
and for css:
#two {
position: absolute;
top: 0px;
}
#wrapper {
position: relative;
}
Aside from the duplicate ID issue noted by Brandt, assigning positioning to table cells is dodgy at best - I'm surprised it works in any browsers. If you must use a table, wrap the elements you want to position in a div and assign the wrapper div position: relative:
<table>
<tr>
<td>
<div class="wrapper">
<div id="three">Three</div>
<div id="two">Two</div>
</div>
</td>
<tr>
</table>
CSS
#two {
position: absolute;
top: 0;
}
.wrapper {
position: relative;
}
In case you want to position stuff at the top and bottom of a cell, also in Firefox, I made it work doing the following mix of CSS and (unfortunately) jQuery.
Use a wrapper div (div.inner) inside your td which has position=relative style in the td. Inside the wrapper I added 2 divs which are to be positioned at the top and bottom of the cell.
Positioning at the top (class=interval-start) is for free, via CSS positioning.
Positioning the div.interval-end at the bottom is done via script, which adds the styling shown in the picture. With variable td-heights and the wrapper div being 0-height by default, you need a way to tell the element how far it should go to the bottom. The script is as follows:
$("table .inner .interval-end").each(function () {
$(this).css({top: ($(this).parent().parent().height() - 10) + "px"})
}).show()
I initially made the div.interval-end invisible, set the 'top' style, and then made it visible via jQuery show().
Hope this helps anybody trying to achieve the same. Let me know if there are better methods out there, specially if these methods do not require scripting. BTW: I tried setting the height style of the wrapper div.inner, but it messes with the table layout in Firefox.
There are legitimate reasons to use CSS display: table styling. It eliminates issues that display: block and display: inline-block do not address. These reasons occupy an entire chapter of a book on CSS styling so I won't go into them here. That same book also describes the problem of positioning within items with that display type. CSS 2.1 specs simply don't address the issue and Mozilla has chosen a course that ignores attempts to create a positioning context with those elements. CSS-table positioning is well established, mature methodology, and not "dodgy" - it just takes understanding of its limits - just like any other CSS element. For liquid layouts and other layouts where element size is variable or unknown it's indispensable for vertical spacing and positioning.
One suggestion in this thread has been presented - create a div within the "table-cell" element set to position: relative and use that for the positioning context. The other method is to embed another CSS table within that cell and use it to position elements within a grid. The third method is to wrap your CSS table within another item that creates a positioning context.

How can I have floating divs to left and right?

I need to show a page with a product icon (which is usually 300x400px in dimensions) on the left side of the page and its details on right side.
I thought I'd put the description in rows of a table.I created 3 div elements- a containerdiv,an icondiv,and a detailsdiv and tried to float the icondiv to left and detailsdiv to right.I got the icondiv on left side of page,but the detailsdiv is shown below the icondiv not side by side!
Ideally the icondiv should be 25-30% in width of containerdiv and detailsdiv should take up the rest of the width.I am wondering if there is a way to do it without mentioning width in pixels.
please correct me if there is something wrong with my css
thanks
mark
<div class ="itemdetailscontainer">
<div class="itemicondiv">
<img border="0" src="${item.isbn }.png" alt="${item.isbn }.png" />
</div>
<div class="itemdetailsdiv">
<table id="itemdetailstable" width="100%">
<tr>
<td>
${item.name }
</td>
</tr>
<tr>
<td>by</td>
</tr>
<tr>
<td>${item.maker.name }</td>
</tr>
<tr>
<td>
<p>Description:</p>
<p>${item.description}</p>
</td>
</tr>
</table>
</div>
</div>
css is
div.itemdetailscontainer{
float:clear;
}
div.itemicondiv{
float:left;
}
div.itemdetailsdiv{
float:right;
}
I tried this
div.itemdetailscontainer{
width:100%;
}
div.itemicondiv{
float:left;
width:25%;
}
div.itemdetailsdiv{
float:right;
width:75%;
}
and this gets the effect..
thanks everyone for responding..Is the use of
width : 25% etc problematic? Do I need to hardcode width in pixels etc?
The overflow property was new for me..
See: http://jsfiddle.net/Uys4s/
div.itemdetailscontainer{
overflow: hidden;
background: #eee
}
div.itemicondiv{
float: left;
width: 30%;
background: #ccc
}
div.itemdetailsdiv{
overflow: hidden;
background: #aaa
}
width: 30% handles this: "Ideally the icondiv should be 25-30% in width of containerdiv"
overflow: hidden on div.itemdetailsdiv handles this: "detailsdiv should take up the rest of the width".
overflow: hidden on div.itemdetailscontainer will contain the floats in the way I think you imagine the nonexistent clear: float will. Take a look at the valid values of clear. If you desperately wanted to use clear: both to clear your floats, this is how you'd do it: http://jsfiddle.net/Uys4s/1/ - but overflow: hidden is easier.
Be sure that your container (itemdetailscontainer) has enough width to hold them side by side. Inspect with Firebug or other tool and check the width.
Also I would suggest you use div's for the itemdetailstable for consistency.
There's nothing called float:clear It should be :
float : none;
or if you're trying to clear the float it should be :
clear:both
float: clear does not exist!
I think you want this: clear: left/right/both

Resources