This is my first post here and I'm by no means a skilled HTML/CSS/JavaScript programmer so please bear with me if I'm not expressing myself clear enough - sorry if it's too wordy!
I'm using a classic HTML table for tabular content and want to be able to change the background color of a different row than the one I'm currently hovering.
The reason for this is that I have many tables that are divided into "sub-tables", each with its own header and one or more rows below. These sub-tables - all with the same styling - are however not coded as tables, instead I simply use different classes to style them (this mainly because they are so many and so small, with 1-6 rows each incl header).
What I want to do is that once you hover any of the sub-tables both its header and the row you're currenty pointing at should change background color (the latter easily achived with CSS). Thanks to a JavaScript found online I've managed to achive this - see sample code which probably explains this better, see also the code below - however that requires a unique ID for each sub-header. (Note that each sub-table uses a separate tbody - if the onMouseover
event was instead applied to each row the color of the sub-header would flicker/go on and off when hovering from one row to another - this never happens with CSS but only with JavaScript - plus creating much more code, of course.)
Instead of having to assign unique IDs to each sub-header I'd like a solution which instead uses the classes, seeing as each sub-table uses the same ones (I'd of course assign a class to tbody
then). I suppose the tricky part with this may be to ensure that just the header of the current sub-table is affected and not all at the same time.
If it's easier to create a solution where each sub-table is in fact coded as a separate table (which may also be better from a semantic point of view?) then please do so. Even better would of course be if the JavaScript applied the onMouseover
etc events by itself, so that I didn't have to put that into the inline code of each sub-table - I've seen that this can be done for buttons etc so I suppose it'd be possible for this to.
I've never used jQuery so a pure JavaScript solution would be much preferred.
For the sample code again please see my fiddle
Many thanks for any input!
The JavaScript:
function changeTo(myId) { document.getElementById(myId).className='sub-header-highlight'; }
function changeBack(myId) { document.getElementById(myId).className='sub-header'; }
The CSS:
thead { color: #FFF; background: #000; }
.sub-header { color: #FFF; font-weight: bold; background: #F00; }
.sub-header-highlight { color:# FFF; font-weight: bold; background: #0F0; }
tr.sub-header:hover { background: #0F0; } /* if JS turned off */
.sub-row1 { color: #000; background: #FFF; }
.sub-row2 { color: #000; background: #EEE; }
tr.sub-row1:hover, .sub-row2:hover { background: #FF0; }
Part of the HTML:
<tbody onMouseover="changeTo('sub1');" onMouseout="changeBack('sub1');">
<tr class="sub-header" id="sub1">
<td>Sub-Header 1</td>
</tr>
<tr class="sub-row1">
<td>Contents of row 1</td>
</tr>
<tr class="sub-row2">
<td>Contents of row 2</td>
</tr>
<tr class="sub-row1">
<td>Contents of row 3</td>
</tr>
</tbody>
This is my first post here and I'm by no means a skilled HTML/CSS/JavaScript programmer so please bear with me if I'm not expressing myself clear enough - sorry if it's too wordy!
I'm using a classic HTML table for tabular content and want to be able to change the background color of a different row than the one I'm currently hovering.
The reason for this is that I have many tables that are divided into "sub-tables", each with its own header and one or more rows below. These sub-tables - all with the same styling - are however not coded as tables, instead I simply use different classes to style them (this mainly because they are so many and so small, with 1-6 rows each incl header).
What I want to do is that once you hover any of the sub-tables both its header and the row you're currenty pointing at should change background color (the latter easily achived with CSS). Thanks to a JavaScript found online I've managed to achive this - see sample code which probably explains this better, see also the code below - however that requires a unique ID for each sub-header. (Note that each sub-table uses a separate tbody - if the onMouseover
event was instead applied to each row the color of the sub-header would flicker/go on and off when hovering from one row to another - this never happens with CSS but only with JavaScript - plus creating much more code, of course.)
Instead of having to assign unique IDs to each sub-header I'd like a solution which instead uses the classes, seeing as each sub-table uses the same ones (I'd of course assign a class to tbody
then). I suppose the tricky part with this may be to ensure that just the header of the current sub-table is affected and not all at the same time.
If it's easier to create a solution where each sub-table is in fact coded as a separate table (which may also be better from a semantic point of view?) then please do so. Even better would of course be if the JavaScript applied the onMouseover
etc events by itself, so that I didn't have to put that into the inline code of each sub-table - I've seen that this can be done for buttons etc so I suppose it'd be possible for this to.
I've never used jQuery so a pure JavaScript solution would be much preferred.
For the sample code again please see my fiddle
Many thanks for any input!
The JavaScript:
function changeTo(myId) { document.getElementById(myId).className='sub-header-highlight'; }
function changeBack(myId) { document.getElementById(myId).className='sub-header'; }
The CSS:
thead { color: #FFF; background: #000; }
.sub-header { color: #FFF; font-weight: bold; background: #F00; }
.sub-header-highlight { color:# FFF; font-weight: bold; background: #0F0; }
tr.sub-header:hover { background: #0F0; } /* if JS turned off */
.sub-row1 { color: #000; background: #FFF; }
.sub-row2 { color: #000; background: #EEE; }
tr.sub-row1:hover, .sub-row2:hover { background: #FF0; }
Part of the HTML:
<tbody onMouseover="changeTo('sub1');" onMouseout="changeBack('sub1');">
<tr class="sub-header" id="sub1">
<td>Sub-Header 1</td>
</tr>
<tr class="sub-row1">
<td>Contents of row 1</td>
</tr>
<tr class="sub-row2">
<td>Contents of row 2</td>
</tr>
<tr class="sub-row1">
<td>Contents of row 3</td>
</tr>
</tbody>
Share
Improve this question
edited Jul 27, 2012 at 18:47
ErikE
50.3k23 gold badges155 silver badges200 bronze badges
asked Jul 27, 2012 at 17:25
Mr LoveMr Love
1031 gold badge1 silver badge9 bronze badges
3
- You should put your code here too. – Alexandre Khoury Commented Jul 27, 2012 at 17:29
- OK, I was trying but couldn't get it to work properly, especially the HTML parts were removed, will try again. – Mr Love Commented Jul 27, 2012 at 17:37
-
If you have a look at the editing help page, it'll show how to format code so it appears. (for in-line code wrap it in backticks
`
, or for blocks of code separate the code with an empty line, before and after, and indent each line by four spaces). – David Thomas Commented Jul 27, 2012 at 17:39
2 Answers
Reset to default 2You can greatly simplify both your HTML markup and CSS, and there is no need to use Javascript.
- First, all the classes can e out except for your alternate row styling (unless you care nothing for IE 8 and below, in which case you can take out the IE conditional CSS and the class names. See the browser CSS selector patibility chart.)
- Second, change each
td
inside a sub-header to ath
. - Third, use the
:hover
pseudo-selector on the parenttbody
to style theth
as specified.
See this working in a jsfiddle, tested to work perfectly in IE 7 and Firefox 14.
Here is the CSS:
table { border-collapse:collapse; }
thead { color: #FFF; background-color: #000; }
tbody th { color: #FFF; font-weight: bold; background-color: #F00; text-align:left; }
tbody:hover th { background: #0F0; }
tbody tr:nth-child(odd) { background-color:#EEE; }
tbody tr:hover td { background: #FF0; }
Style Notes:
- The CSS property "background" expects more than just color, and will reset the other properties as well. Use "background-color" when that's all you want to style.
- The extra
td
on thetr:hover
is required in order for specificity rules to make IE give it a higher precedence than the special coloring for odd rows. - The "odd" rows are really the even ones of the data, because the sub-header consumes the first odd row.
- Use CSS
border-collapse:collapse
instead ofcellspacing
directly on the table.
I had to put the conditional CSS for IE in the HTML section of the fiddle since it must be outside the style
tag.
<!--[if lte IE 8]>
<style type="text/css">
tbody tr.odd { color: #000; background: #EEE; }
</style>
<![endif]-->
And here's the HTML. See how clean it is now?
<table>
<thead>
<tr>
<th>MAIN HEADER</th>
</tr>
</thead>
<tbody>
<tr>
<th>Sub-Header 1</th>
</tr>
<tr>
<td>Contents of row 1</td>
</tr>
<tr class="odd">
<td>Contents of row 2</td>
</tr>
<tr>
<td>Contents of row 3</td>
</tr>
</tbody>
<tbody>
<tr>
<th>Sub-Header 2</th>
</tr>
<tr>
<td>Contents of row 1</td>
</tr>
</tbody>
<tbody>
<tr>
<th>Sub-Header 3</th>
</tr>
<tr>
<td>Contents of row 1</td>
</tr>
<tr class="odd">
<td>Contents of row 2</td>
</tr>
</tbody>
</table>
Finally, I realize the colors were probably just examples, so may I suggest that bright primary colors are not going to work well with human cognitive response? You could go for a sort of highlighting effect instead. See a working example that I put together for you, using colors that are (to my eye) more pleasing. See how the section kind of "glows" when you hover over it? Beautiful!
Note: In IE8 and before, there will be an extra border on the right side. If you have a multi-column table and you like the inside border thing and want to support IE8 and below, you'll need to add a class to the last cell in each row so it can have its right border removed.
You can achieve this with pure CSS (with the usual browser-patibility provisos), so assuming you're using a relatively modern Chrome, Safari, Firefox, Opera or, possibly, IE 9 (or greater):
tbody:hover tr.sub-header {
background-color: #0f0;
}
tbody tr.sub-row:hover {
background-color: #f90;
}
JS Fiddle demo (obviously, adapt the colours to your taste; these were just for the purposes of a demonstration).
It is, of course, worth mentioning that some browsers might not show the tr
element's background-color
(since it displays behind the background-color
of the td
elements), in that case you might need to amend the selectors to target the relevant td
elements instead:
tbody:hover tr.sub-header td {
background-color: #0f0;
}
tbody tr.sub-row:hover td {
background-color: #f90;
}