Default behavior on HTML borders seems to differ with cell background color, imposing some sort of contrast which overrides a defined border color. I have attempted to trace the problem to turn off this override, but cannot find where it comes from.
The example below demonstrates the issue:
table, th, td {
border: 1px solid black;
border-collapse: collapse;
border-color: lightgray;
}
.lav {
background-color: lavender;
}
.medBlue {
background-color: mediumblue;
}
<body>
<table>
<tr class="lav">
<th>Firstname</th>
<th>_</th>
<th>Lastname</th>
</tr>
<tr class="lav">
<td>Peter</td>
<td>_</td>
<td>Griffin</td>
</tr>
<tr class="medBlue">
<td>Lois</td>
<td>_</td>
<td>Griffin</td>
</tr>
</table>
</body>
The first two rows have a border color of light gray, as expected. However, the third row with the darker background has its border color overridden with a different color.
How can I make border colors in this table uniform?
A similar question is asked here, but I don't think this issue has to do with transparency (at minimum, the border color on the darker cells would then be darker, not lighter).
The issue seems to relate to the degree of zoom, which leads me to believe it is a correction made by the browser for when the width of the border is (arbitrarily?) deemed too small. In other words, the color is changed to as-intended when zooming in on the table. A work-around is to simply make the border thicker, but I would like to avoid this. The issue holds when using PhantomJS to load such tables and subsequently screenshot them, which is what I need this code for.
The only thing you can do is to increase the border color darkness to please the eyes . .medBlue td {border-color: gray; }.
table, th, td {
border: 1px solid black;
border-collapse: collapse;
border-color: lightgray;
}
.lav {
background-color: lavender;
}
.medBlue {
background-color: mediumblue;
}
.medBlue td {
border-color: gray;
}
<body>
<table>
<tr class="lav">
<th>Firstname</th>
<th>_</th>
<th>Lastname</th>
</tr>
<tr class="lav">
<td>Peter</td>
<td>_</td>
<td>Griffin</td>
</tr>
<tr class="medBlue">
<td>Lois</td>
<td>_</td>
<td>Griffin</td>
</tr>
</table>
</body>
So I want to select a specific table row and change the background color. I know I can code it via html. But I would rather do it through CSS. I tried giving the table row a class name, but it still wont change the background color. I'm trying to change the background of the class "update". https://jsfiddle.net/q0395cyc/
<table class="table3">
<tbody>
<tr class="update">
<td >
FUNDRAISING UPDATE: $2.5 million in commited capital
</td>
</tr>
First fix your HTML syntax errors (unclosed tbody, tables etc...)
TR are not meant for design. Forget they exist.
TRs are just a way to tell the browser where your TDs group spans/ends.
Style the inner TD instead
.update td {
background: red;
}
Example trying to style TR:
tr.styled{
background: red; /* will become red but... don't. */
border-radius: 10px; /* this will not work */
padding: 10px; /* neither will this */
/* neither many other styles here */
}
<table>
<tr class="styled">
<td>Special offer</td>
</tr>
</table>
Styling inner TD:
tr.styled td{
background: red;
border-radius: 5px;
padding: 10px;
}
<table>
<tr class="styled">
<td>Special offer</td>
</tr>
</table>
I would like to create a table header row that includes a title on the left as well as "Sample header" on the right. For accessibility and to be semantically correct, the title should probably be in a <caption> tag, but "Sample header" isn't part of the title so it probably shouldn't be inside of <caption>. The caption can't be inside the row since it has to be the first element after <table>.
Here is the HTML structure:
<table>
<caption>Caption</caption>
<thead>
<tr class="sample">
<th colspan="2">Sample header</th>
</tr>
<tr>
<th>Column1</th>
<th>Column2</th>
</tr>
</thead>
<tbody>
<tr>
<td>Data1</td>
<td>Data2</td>
</tr>
</tbody>
</table>
The caption ends up as a separate line above the table, while I would like it to be on the same line as "Sample header".
Here is a sample of what I'm trying to achieve: http://jsfiddle.net/vueLL5ce/5/. It sets 'caption`'s position to relative and manually moves it where I want. The two main problems with this approach is that repositioning the caption still leaves its original space above the table and I'm working with pixels which vary between browsers so it won't necessarily line up correctly.
Is there a good way of achieving this? Am I stuck with including the header info inside of <caption> (and styling to look like a table row) or creating a regular table row and not using <caption>?
Move background color from div to table and it should remove the color from the top for you. see attached fiddle here
table {
border: solid 1px Black;
width: 100%;
background-color: #FFFFDD;
}
I would remove the caption, use the column head and separate the two items with there own class then align them in your css. Updated the example here This way you don't have the spacing issue at all.
I think I found a cross-browser solution. The key is to set line-height: 0 (plain 0 doesn't work in IE6, but I don't need to support it). Firefox also wouldn't let me reposition the caption directly, so I had to add another span. I still don't like dealing with pixels directly, so any suggestions on that end would be great.
Fiddle: http://jsfiddle.net/vueLL5ce/8/
HTML:
<div>
<table>
<caption><span>Caption</span></caption>
<thead>
<tr class="captionRow">
<th colspan="2">Sample header</th>
</tr>
<tr>
<th>Column1</th>
<th>Column2</th>
</tr>
</thead>
<tbody>
<tr>
<td>Data1</td>
<td>Data2</td>
</tr>
</tbody>
</table>
</div>
CSS:
div {
background-color: #FFFFDD;
}
table {
border: solid 1px Black;
width: 100%;
}
table caption {
line-height: 0;
text-align: left;
}
table caption span {
position: relative;
left: 4px;
top: 14px;
}
table th {
background-color: #CCC;
}
.captionRow th {
text-align: right;
}
This is probably a very basic question but I cant figure it out with standard approach. I have a table in which I am trying to do a different styling for one column. I thought that the easiest way to do this would use a class="class" property inside this column and then apply styling on it but it doesnt work.
This is exmaple of my table (its filled with JSON objects but its not important now):
<table id="logtable" class="pretty">
<thead>
<tr>
<th>Time</th>
<th>From</th>
<th>To</th>
<th>Payload</th>
</tr>
</thead>
<tbody>
<c:forEach var="message" items="${messages}">
<tr>
<td><c:out value="${message.timestamp}" /></td>
<td><c:out value="${message.sender}" /></td>
<td><c:out value="${message.receiver}" /></td>
<td class="message"><c:out value="${message.payload}" /></td>
</tr>
</c:forEach>
</tbody>
</table>
This is the CSS I use (part of it):
table.pretty tbody td {
text-align: center;
background: #DEE7EF;
}
This works but when I try to style the last column like this, it doesnt do anything:
table.pretty tbody td .message {
text-align: left;
}
What am I doing wrong? Thanks for any tips!
You just need:
table.pretty tbody .message {
text-align: left;
}
(skip the td).
This is because .message means basically "any element with the class message".
On the other hand, td .message means "any element with the class message inside any td element.
You have space betweeb td and message,
replace
table.pretty tbody td .message {
with
table.pretty tbody td.message {
td .message this css selector means you are selecting .message which parent is td.
while td.message means td having message class.
Have you tried the following?
table.pretty tbody td.message {
text-align: left;
}
I believe the td .message is trying to find a child to the td-element with a class of "message".
Example: http://jsfiddle.net/Sb2w4/
I want to make an html table with the top row frozen (so when you scroll down vertically you can always see it).
Is there a clever way to make this happen without javascript?
Note that I do NOT need the left column frozen.
I know this has several answers, but none of these really helped me. I found this article which explains why my sticky wasn't operating as expected.
Basically, you cannot use position: sticky; on <thead> or <tr> elements. However, they can be used on <th>.
The minimum code I needed to make it work is as follows:
table {
text-align: left;
position: relative;
}
th {
background: white;
position: sticky;
top: 0;
}
With the table set to relative the <th> can be set to sticky, with the top at 0
NOTE: It's necessary to wrap the table with a div with max-height:
<div id="managerTable" >
...
</div>
where:
#managerTable {
max-height: 500px;
overflow: auto;
}
This is called Fixed Header Scrolling. There are a number of documented approaches:
http://www.imaputz.com/cssStuff/bigFourVersion.html
You won't effectively pull this off without JavaScript ... especially if you want cross browser support.
There are a number of gotchyas with any approach you take, especially concerning cross browser/version support.
Edit:
Even if it's not the header you want to fix, but the first row of data, the concept is still the same. I wasn't 100% which you were referring to.
Additional thought
I was tasked by my company to research a solution for this that could function in IE7+, Firefox, and Chrome.
After many moons of searching, trying, and frustration it really boiled down to a fundamental problem. For the most part, in order to gain the fixed header, you need to implement fixed height/width columns because most solutions involve using two separate tables, one for the header which will float and stay in place over the second table that contains the data.
//float this one right over second table
<table>
<tr>
<th>Header 1</th>
<th>Header 2</th>
</tr>
</table>
<table>
//Data
</table>
An alternative approach some try is utilize the tbody and thead tags but that is flawed too because IE will not allow you put a scrollbar on the tbody which means you can't limit its height (so stupid IMO).
<table>
<thead style="do some stuff to fix its position">
<tr>
<th>Header 1</th>
<th>Header 2</th>
</tr>
</thead>
<tbody style="No scrolling allowed here!">
Data here
</tbody>
</table>
This approach has many issues such as ensures EXACT pixel widths because tables are so cute in that different browsers will allocate pixels differently based on calculations and you simply CANNOT (AFAIK) guarantee that the distribution will be perfect in all cases. It becomes glaringly obvious if you have borders within your table.
I took a different approach and said screw tables since you can't make this guarantee. I used divs to mimic tables. This also has issues of positioning the rows and columns (mainly because floating has issues, using in-line block won't work for IE7, so it really left me with using absolute positioning to put them in their proper places).
There is someone out there that made the Slick Grid which has a very similar approach to mine and you can use and a good (albeit complex) example for achieving this.
https://github.com/6pac/SlickGrid/wiki
According to Pure CSS Scrollable Table with Fixed Header , I wrote a DEMO to easily fix the header by setting overflow:auto to the tbody.
table thead tr{
display:block;
}
table th,table td{
width:100px;//fixed width
}
table tbody{
display:block;
height:200px;
overflow:auto;//set tbody to auto
}
My concern was not to have the cells with fixed width. Which seemed to be not working in any case.
I found this solution which seems to be what I need. I am posting it here for others who are searching of a way. Check out this fiddle
Working Snippet:
html, body{
margin:0;
padding:0;
height:100%;
}
section {
position: relative;
border: 1px solid #000;
padding-top: 37px;
background: #500;
}
section.positioned {
position: absolute;
top:100px;
left:100px;
width:800px;
box-shadow: 0 0 15px #333;
}
.container {
overflow-y: auto;
height: 160px;
}
table {
border-spacing: 0;
width:100%;
}
td + td {
border-left:1px solid #eee;
}
td, th {
border-bottom:1px solid #eee;
background: #ddd;
color: #000;
padding: 10px 25px;
}
th {
height: 0;
line-height: 0;
padding-top: 0;
padding-bottom: 0;
color: transparent;
border: none;
white-space: nowrap;
}
th div{
position: absolute;
background: transparent;
color: #fff;
padding: 9px 25px;
top: 0;
margin-left: -25px;
line-height: normal;
border-left: 1px solid #800;
}
th:first-child div{
border: none;
}
<section class="">
<div class="container">
<table>
<thead>
<tr class="header">
<th>
Table attribute name
<div>Table attribute name</div>
</th>
<th>
Value
<div>Value</div>
</th>
<th>
Description
<div>Description</div>
</th>
</tr>
</thead>
<tbody>
<tr>
<td>align</td>
<td>left, center, right</td>
<td>Not supported in HTML5. Deprecated in HTML 4.01. Specifies the alignment of a table according to surrounding text</td>
</tr>
<tr>
<td>bgcolor</td>
<td>rgb(x,x,x), #xxxxxx, colorname</td>
<td>Not supported in HTML5. Deprecated in HTML 4.01. Specifies the background color for a table</td>
</tr>
<tr>
<td>border</td>
<td>1,""</td>
<td>Specifies whether the table cells should have borders or not</td>
</tr>
<tr>
<td>cellpadding</td>
<td>pixels</td>
<td>Not supported in HTML5. Specifies the space between the cell wall and the cell content</td>
</tr>
<tr>
<td>cellspacing</td>
<td>pixels</td>
<td>Not supported in HTML5. Specifies the space between cells</td>
</tr>
<tr>
<td>frame</td>
<td>void, above, below, hsides, lhs, rhs, vsides, box, border</td>
<td>Not supported in HTML5. Specifies which parts of the outside borders that should be visible</td>
</tr>
<tr>
<td>rules</td>
<td>none, groups, rows, cols, all</td>
<td>Not supported in HTML5. Specifies which parts of the inside borders that should be visible</td>
</tr>
<tr>
<td>summary</td>
<td>text</td>
<td>Not supported in HTML5. Specifies a summary of the content of a table</td>
</tr>
<tr>
<td>width</td>
<td>pixels, %</td>
<td>Not supported in HTML5. Specifies the width of a table</td>
</tr>
</tbody>
</table>
</div>
</section>
You can use CSS position: sticky; for the first row of the table
MDN ref:
.table-class tr:first-child>td{
position: sticky;
top: 0;
}
you can use two divs one for the headings and the other for the table. then use
#headings {
position: fixed;
top: 0px;
width: 960px;
}
as #ptriek said this will only work for fixed width columns.
It is possible using position:fixed on <th> (<th> being the top row).
Here's an example
The Chromatable jquery plugin allows a fixed header (or top row) with widths that allow percentages--granted, only a percentage of 100%.
http://www.chromaloop.com/posts/chromatable-jquery-plugin
I can't think of how you could do this without javascript.
update: new link -> http://www.jquery-plugins.info/chromatable-00012248.htm
I use this:
tbody{
overflow-y: auto;
height: 350px;
width: 102%;
}
thead,tbody{
display: block;
}
I define the columns width with bootstrap css col-md-xx. Without defining the columns width the auto-width of the doesn't match the . The 102% percent is because you lose some sapce with the overflow
Using css zebra styling
Copy paste this example and see the header fixed.
<style>
.zebra tr:nth-child(odd){
background:white;
color:black;
}
.zebra tr:nth-child(even){
background: grey;
color:black;
}
.zebra tr:nth-child(1) {
background:black;
color:yellow;
position: fixed;
margin:-30px 0px 0px 0px;
}
</style>
<DIV id= "stripped_div"
class= "zebra"
style = "
border:solid 1px red;
height:15px;
width:200px;
overflow-x:none;
overflow-y:scroll;
padding:30px 0px 0px 0px;"
>
<table>
<tr >
<td>Name:</td>
<td>Age:</td>
</tr>
<tr >
<td>Peter</td>
<td>10</td>
</tr>
</table>
</DIV>
Notice the top padding of of 30px in the div leaves
space that is utilized by the 1st row of stripped data
ie tr:nth-child(1) that is "fixed position"
and formatted to a margin of -30px