Css hover isn't working - html

Here is my code. I made this - when I hover table cell then its background image changes, that was easy.
But I would like to make that when I hover cell 5 with class="down" in first table then second table display attribute changes from none to block
I searched for this and I ended up with all this code, and it isn't working.
I need to use pure CSS without JavaScript.
Where is the problem and what did I do wrong?
HTML
<table border="0" class="table">
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td class="down">5</td>
</tr>
</table>
<table border="0" class="table2">
<tr>
<td>row2</td>
</tr>
<tr>
<td>row3</td>
</tr>
</table>
CSS
.table
{
left:200px;
position:absolute;
}
td
{
background-image:url(poga1.png);
height:70px;
width:100px;
}
td:hover
{
-webkit-transition:1s;
background-image:url(poga2.png);
}
.table2
{
display:none;
left:616px;
position:absolute;
top:77px;
}
.down:hover .table2
{
display:block;
}

You can't really do this with CSS unless Table2 is a child of Table1. It can be done very easily with JavaScript though (w/ jQuery in this instance). Check out my example here:
http://jsfiddle.net/Pb8dw/1/
$(document).ready(function() {
$(".down").mouseover(function(){
$(".table2").show();
});
$(".down").mouseout(function(){
$(".table2").hide();
});
});
This is the block of code that does the hide/show on hover. I took the liberty of updating your source code so it's easier to see.
Update: If you absolutely, positively, had to do it without JavaScript, here's how it would be down with just CSS and HTML:
http://jsfiddle.net/Pb8dw/2/

The line .down:hover .table2 is looking for an element with class table2 inside an element with class down. You can only do what you want in pure CSS if your tables are nested. Here's how you might do what you want using jQuery:
$(document).ready(function() {
$('.down').hover(function() {
$('.table2').show();
}, function() {
$('.table2').hide();
});
});
Here's a demo: http://jsfiddle.net/mchail/b6PKT/
I added a border on the td elements so it's easier to see when your hover event should trigger.

Related

Vuetify table styles broken when adding a tag in tr [duplicate]

I'm using Bootstrap and the following doesn't work:
<tbody>
<a href="#">
<tr>
<td>Blah Blah</td>
<td>1234567</td>
<td>£158,000</td>
</tr>
</a>
</tbody>
Author's note I:
Please look at other answers below, especially ones that do not use jquery.
Author's note II:
Preserved for posterity but surely the wrong approach in 2020. (Was non idiomatic even back in 2017)
Original Answer
You are using Bootstrap which means you are using jQuery :^), so one way to do it is:
<tbody>
<tr class='clickable-row' data-href='url://'>
<td>Blah Blah</td> <td>1234567</td> <td>£158,000</td>
</tr>
</tbody>
jQuery(document).ready(function($) {
$(".clickable-row").click(function() {
window.location = $(this).data("href");
});
});
Of course you don't have to use href or switch locations, you can do whatever you like in the click handler function. Read up on jQuery and how to write handlers;
Advantage of using a class over id is that you can apply the solution to multiple rows:
<tbody>
<tr class='clickable-row' data-href='url://link-for-first-row/'>
<td>Blah Blah</td> <td>1234567</td> <td>£158,000</td>
</tr>
<tr class='clickable-row' data-href='url://some-other-link/'>
<td>More money</td> <td>1234567</td> <td>£800,000</td>
</tr>
</tbody>
and your code base doesn't change. The same handler would take care of all the rows.
Another option
You can use Bootstrap jQuery callbacks like this (in a document.ready callback):
$("#container").on('click-row.bs.table', function (e, row, $element) {
window.location = $element.data('href');
});
This has the advantage of not being reset upon table sorting (which happens with the other option).
Note
Since this was posted window.document.location is obsolete (or deprecated at the very least) use window.location instead.
You can't do that. It is invalid HTML. You can't put a <a> in between a <tbody> and a <tr>. Try this instead:
<tr onclick="window.location='#';">
...
</tr>
add style for pointer view
[data-href] { cursor: pointer; }
When you work up to it, you'd want to use JavaScript to assign the click handler outside the HTML.
You could include an anchor inside every <td>, like so:
<tr>
<td>Blah Blah</td>
<td>1234567</td>
<td>more text</td>
</tr>
You could then use display:block; on the anchors to make the full row clickable.
tr:hover {
background: red;
}
td a {
display: block;
border: 1px solid black;
padding: 16px;
}
Example jsFiddle here.
This is probably about as optimum as you're going to get it unless you resort to JavaScript.
A linked table row is possible, but not with the standard <table> elements. You can do it using the display: table style properties. Here and here are some fiddles to demonstrate.
This code should do the trick:
.table {
display: table;
}
.row {
display: table-row;
}
.cell {
display: table-cell;
padding: 10px;
}
.row:hover {
background-color: #cccccc;
}
.cell:hover {
background-color: #e5e5e5;
}
<link href="https://stackpath.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet" type="text/css" />
<div role="grid" class="table">
<div role="row" class="row">
<div role="gridcell" class="cell">
1.1
</div>
<div role="gridcell" class="cell">
1.2
</div>
<div role="gridcell" class="cell">
1.3
</div>
</div>
<a role="row" class="row" href="#">
<div role="gridcell" class="cell">
2.1
</div>
<div role="gridcell" class="cell">
2.2
</div>
<div role="gridcell" class="cell">
2.3
</div>
</a>
</div>
Note that ARIA roles are needed to ensure proper accessibility since the standard <table> elements are not used. You may need to add additional roles like role="columnheader" if applicable. Find out more at the guide here.
Achieved using standard Bootstrap 4.3+ as follows - no jQuery nor any extra css classes needed!
The key is to use stretched-link on the text within the cell and defining <tr> as a containing block.
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"/>
<table class="table table-hover">
<tbody>
<tr style="transform: rotate(0);">
<th scope="row">1</th>
<td>Mark</td>
<td>Otto</td>
<td>#mdo</td>
</tr>
<tr>
<th scope="row">2</th>
<td>Jacob</td>
<td>Thornton</td>
<td>#fat</td>
</tr>
<tr>
<th scope="row">3</th>
<td>Larry</td>
<td>the Bird</td>
<td>#twitter</td>
</tr>
</tbody>
</table>
You can define containing block in different ways for example setting transform to not none value (as in example above).
For more information read here's the Bootstrap documentation for stretched-link.
A much more flexible solution is to target anything with the data-href attribute. This was you can reuse the code easily in different places.
<tbody>
<tr data-href="https://google.com">
<td>Col 1</td>
<td>Col 2</td>
</tr>
</tbody>
Then in your jQuery just target any element with that attribute:
jQuery(document).ready(function($) {
$('*[data-href]').on('click', function() {
window.location = $(this).data("href");
});
});
And don't forget to style your css:
[data-href] {
cursor: pointer;
}
Now you can add the data-href attribute to any element and it will work. When I write snippets like this I like them to be flexible. Feel free to add a vanilla js solution to this if you have one.
One solution that was not mentioned earlier is to use a single link in a cell and some CSS to extend this link over the cells:
table {
border: 1px solid;
width: 400px;
overflow: hidden;
}
tr:hover {
background: gray;
}
tr td {
border: 1px solid;
}
tr td:first-child {
position:relative;
}
a:before {
content: '';
position:absolute;
left: 0;
top: 0;
bottom: 0;
display: block;
width: 400px;
}
<table>
<tr>
<td>First column</td>
<td>Second column</td>
<td>Third column</td>
</tr>
<tr>
<td>First column</td>
<td>Second column</td>
<td>Third column</td>
</tr>
</table>
Here is simple solution..
<tr style='cursor: pointer; cursor: hand;' onclick="window.location='google.com';"></tr>
You can use this bootstrap component:
http://jasny.github.io/bootstrap/javascript/#rowlink
Jasny Bootstrap
The missing components for your favorite front-end framework.
<table class="table table-striped table-bordered table-hover">
<thead>
<tr><th>Name</th><th>Description</th><th>Actions</th></tr>
</thead>
<tbody data-link="row" class="rowlink">
<tr><td>Input mask</td><td>Input masks can be used to force the user to enter data conform a specific format.</td><td class="rowlink-skip">Action</td></tr>
<tr><td>jasny.net</td><td>Shared knowledge of Arnold Daniels aka Jasny.</td><td class="rowlink-skip">Action</td></tr>
<tr><td>Launch modal</td><td>Toggle a modal via JavaScript by clicking this row.</td><td class="rowlink-skip">Action</td></tr>
</tbody>
</table>
Usage
Via data attributes
Add class .rowlink and attribute data-link="row" to a <table> or <tbody> element. For other options append the name to data-, as in data-target="a.mainlink" A cell can be excluded by adding the .rowlink-skip class to the <td>.
Via JavaScript
Call the input mask via javascript:
$('tbody.rowlink').rowlink()
You can add the button role to a table row and Bootstrap will change the cursor without any css changes. I decided to use that role as a way to easily make any row clickable with very little code.
Html
<table class="table table-striped table-hover">
<tbody>
<tr role="button" data-href="#">
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
</tbody>
</table>
jQuery
$(function(){
$(".table").on("click", "tr[role=\"button\"]", function (e) {
window.location = $(this).data("href");
});
});
You can apply this same principle to add the button role to any tag.
There is a nice way to technically do it with <a> tag inside <tr>, which might be semantically incorrect (might give you a browser warning), but will work with no JavaScript/jQuery required:
<!-- HTML -->
<tbody>
<tr class="bs-table-row">
<td>Blah Blah</td>
<td>1234567</td>
<td>£158,000</td>
<a class="bs-row-link" href="/your-link-here"></a>
</tr>
</tbody>
/* CSS */
.bs-table-row {
position: 'relative';
}
.bs-row-link {
position: 'absolute';
left: 0;
height: '36px'; // or different row height based on your requirements
width: '100%';
cursor: 'pointer';
}
PS: Notice the trick here is to put <a> tag as last element, otherwise it will try to take the space of the first <td> cell.
PPS: Now your entire row will be clickable and you can use this link to open in new tab as well (Ctrl/CMD+click)
A very easy option is just use on-click, and more correct, in my point of view, because this separate the view and controller, and you don't need to hard code the URL or whatever more you need do accomplish with the click.
It works with Angular ng-click too.
<table>
<tr onclick="myFunction(this)">
<td>Click to show rowIndex</td>
</tr>
</table>
<script>
function myFunction(x) {
alert("Row index is: " + x.rowIndex);
}
</script>
Exemple working here
You can use onclick javascript method in tr and make it clickable, also if you need to build your link due to some details you can declare a function in javascript and call it in onclick, passing some values.
Here is a way by putting a transparent A element over the table rows. Advantages are:
is a real link element: on hover changes pointer, shows target link in status bar, can be keyboard navigated, can be opened in new tab or window, the URL can be copied, etc
the table looks the same as without the link added
no changes in table code itself
Disadvantages:
size of the A element must be set in a script, both on creation and after any changes to the size of the row it covers (otherwise it could be done with no JavaScript at all, which is still possible if the table size is also set in HTML or CSS)
The table stays as is:
<table id="tab1">
<tbody>
<tr>
<td>Blah Blah</td>
<td>1234567</td>
<td>£158,000</td>
</tr>
</tbody>
</table>
Add the links (for each row) via jQuery JavaScript by inserting an A element into each first column and setting the needed properties:
// v1, fixed for IE and Chrome
// v0, worked on Firefox only
// width needed for adjusting the width of the A element
var mywidth=$('#tab1').width();
$('#tab1 tbody>tr>td:nth-child(1)').each(function(index){
$(this).css('position', 'relative');// debug: .css('background-color', '#f11');
// insert the <A> element
var myA=$('<A>');
$(this).append(myA);
var myheight=$(this).height();
myA.css({//"border":'1px solid #2dd', border for debug only
'display': 'block',
'left': '0',
'top': '0',
'position': 'absolute'
})
.attr('href','the link here')
.width(mywidth)
.height(myheight)
;
});
The width and height setting can be tricky, if many paddings and margins are used, but in general a few pixels off should not even matter.
Live demo here: http://jsfiddle.net/qo0dx0oo/ (works in Firefox, but not IE or Chrome, there the link is positioned wrong)
Fixed for Chrome and IE (still works in FF too): http://jsfiddle.net/qo0dx0oo/2/
This code bellow will make your whole table clickable. Clicking the links in this example will show the link in an alert dialog instead of following the link.
The HTML:
Here's the HTML behind the above example:
<table id="example">
<tr>
<th> </th>
<th>Name</th>
<th>Description</th>
<th>Price</th>
</tr>
<tr>
<td>Edit</td>
<td>Apples</td>
<td>Blah blah blah blah</td>
<td>10.23</td>
</tr>
<tr>
<td>Edit</td>
<td>Bananas</td>
<td>Blah blah blah blah</td>
<td>11.45</td>
</tr>
<tr>
<td>Edit</td>
<td>Oranges</td>
<td>Blah blah blah blah</td>
<td>12.56</td>
</tr>
</table>
The CSS
And the CSS:
table#example {
border-collapse: collapse;
}
#example tr {
background-color: #eee;
border-top: 1px solid #fff;
}
#example tr:hover {
background-color: #ccc;
}
#example th {
background-color: #fff;
}
#example th, #example td {
padding: 3px 5px;
}
#example td:hover {
cursor: pointer;
}
The jQuery
And finally the jQuery which makes the magic happen:
$(document).ready(function() {
$('#example tr').click(function() {
var href = $(this).find("a").attr("href");
if(href) {
window.location = href;
}
});
});
What it does is when a row is clicked, a search is done for the href belonging to an anchor. If one is found, the window's location is set to that href.
I know someone has written pretty much the same already, however my way is the correct way (div cannot be child of A) and also it's better to use classes.
You can imitate a table using CSS and make an A element the row
<div class="table" style="width:100%;">
<a href="#" class="tr">
<span class="td">
cell 1
</span>
<span class="td">
cell 2
</span>
</a>
</div>
css:
.table{display:table;}
.tr{display:table-row;}
.td{display:table-cell;}
.tr:hover{background-color:#ccc;}
i would prefer to use onclick="" attribute as it is easy to use and understand for newbie like
<tr onclick="window.location='any-page.php'">
<td>UserName</td>
<td>Email</td>
<td>Address</td>
</tr>
Here's an article that explains how to approach doing this in 2020: https://www.robertcooper.me/table-row-links
The article explains 3 possible solutions:
Using JavaScript.
Wrapping all table cells with anchorm elements.
Using <div> elements instead of native HTML table elements in order to have tables rows as <a> elements.
The article goes into depth on how to implement each solution (with links to CodePens) and also considers edge cases, such as how to approach a situation where you want to add links inside you table cells (having nested <a> elements is not valid HTML, so you need to workaround that).
As #gameliela pointed out, it may also be worth trying to find an approach where you don't make your entire row a link, since it will simplify a lot of things. I do, however, think that it can be a good user experience to have an entire table row clickable as a link since it is convenient for the user to be able to click anywhere on a table to navigate to the corresponding page.
Another option using an <a>, CSS positions and some jQuery or JS:
HTML:
<table>
<tr>
<td>
<span>1</span>
</td>
<td><span>2</span></td>
</tr>
</table>
CSS:
table tr td:first-child {
position: relative;
}
a.rowLink {
position: absolute;
top: 0; left: 0;
height: 30px;
}
a.rowLink:hover {
background-color: #0679a6;
opacity: 0.1;
}
Then you need to give the a width, using for example jQuery:
$(function () {
var $table = $('table');
$links = $table.find('a.rowLink');
$(window).resize(function () {
$links.width($table.width());
});
$(window).trigger('resize');
});
The accepted answer is great, but I propose a small alternative if you don't want to repeat the url on every tr.
So you put the url or href in the table data-url and not the tr.
<table data-click data-url="href://blah">
<tbody>
<tr id ="2">
<td>Blah Blah</td> <td>1234567</td> <td>£158,000</td>
</tr>
<tr id ="3">
<td>Blah Blah</td> <td>1234567</td> <td>£158,000</td>
</tr>
</tbody>
</table
jQuery(document).ready(function($) {
$('[data-click] tbody tr').click(function() {
var url = $(this).closest('table').data("url");
var id = $(this).closest('tr').attr('id');
window.location = url+"?id="+id);
});
});
This is also good because you don't need to add the click data attribute to every tr either. The other good thing is that we are not using a class to trigger a click as classes should only really be used for styling.
<tbody>
<tr data-href='www.bbc.co.uk'>
<td>Blah Blah</td>
<td>1234567</td>
<td>£158,000</td>
</tr>
<tr data-href='www.google.com'>
<td>Blah Blah</td>
<td>1234567</td>
<td>£158,000</td>
</tr>
</tbody>
<script>
jQuery(document).ready(function ($) {
$('[data-href]').click(function () {
window.location = $(this).data("href");
});
});
</script>
Whilst the main solution on here is great, my solution removes the need for classes. All you need to do is add the data-href attribute with the URL in it.
I've invested a lot of time trying to solve this problem.
There are 3 approaches:
Use JavaScript. The clear drawbacks: it's not possible to open a new tab natively, and when hovering over the row there will be no indication on status bar like regular links have. Accessibility is also a question.
Use HTML/CSS only. This means putting <a> nested under each <td>. A simple approach like this fiddle doesn't work - Because the clickable surface is not necessarily equal for each column. This is a serious UX concern. Also, if you need a <button> on the row, it is not valid HTML to nest it under <a> tag (although browsers are ok with that).
I've found 3 other ways to implement this approach. First is ok, the other two are not great.
a) Have a look on this example:
tr {
height: 0;
}
td {
height: 0;
padding: 0;
}
/* A hack to overcome differences between Chrome and Firefox */
#-moz-document url-prefix() {
td {
height: 100%;
}
}
a {
display: block;
height: 100%;
}
It works, but due to inconsistencies between Chrome and Firefox it requires browser-specific hack to overcome the differences. Also Chrome will always align the cell content to the top, which can cause problems with long texts, especially if varying line heights are involved.
b) Setting <td> to { display: contents; }. This leads to 2 other problems:
b1. If someone else tries to style directly the <td> tag, like setting it to { width: 20px; }, we need to pass that style somehow to the <a> tag. We need some magic to do that, probably more magic than in the Javascript alternative.
b2. { display: contents; } is still experimental; specifically it's not supported on Edge.
c) Setting <td> to { height: --some-fixed-value; }. This is just not flexible enough.
The last approach, which I recommend to seriously thinking of, is to not using clickable rows at all. Clickable rows is not a great UX experience: it's not easy to visually mark them as clickable, and it poses challenges when multiple parts are clickable within the rows, like buttons. So a viable alternative could be to have an <a> tag only on the first column, displayed as a regular link, and give it the role of navigating the whole row.
Here's a generic approach. Define this css:
// css
td a.linker {
color:#212529;
display: block;
padding: 16px;
text-decoration: none;
}
Then place this inside each td:
<td>
<a class="linker" href="www.google.com">
Cell content goes here
</a>
</td>
Here is another way...
The HTML:
<table>
<tbody>
<tr class='clickableRow'>
<td>Blah Blah</td>
<td>1234567</td>
<td>£158,000</td>
</tr>
</tbody>
</table>
The jQuery:
$(function() {
$(".clickableRow").on("click", function() {
location.href="http://google.com";
});
});
<table>
<tr tabindex="0" onmousedown="window.location='#';">
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
</table>
Replace # with the url, tabindex="0" makes any element focusable
A 2023 answer:
You can add an addEventListener to the row:
var rows = document.getElementsByTagName('table')[0].rows;
Array.from(rows).forEach(row => {
row.addEventListener("click", function() {
console.log(this.getAttribute('data-href'));
// window.location.href = this.getAttribute('data-href');
});
});
body {
display: flex;
justify-content: center;
margin-top: 20px;
color: #37559d;
}
a {
color: #5165ff;
}
table {
border-collapse: collapse;
}
tr:hover {
background: #f2f3ff;
outline: none;
cursor: pointer;
}
td {
border: 2px solid #ccd2ff;
position: relative;
padding: 18px;
}
<table>
<tbody>
<tr data-href="https://www.google.com">
<td>One</td>
<td>Two</td>
<td>Three</td>
<td>Four</td>
<td>
Link
</td>
</tr>
<tr data-href="https://www.amazon.com">
<td>One</td>
<td>Two</td>
<td>Three</td>
<td>Four</td>
<td>
Link
</td>
</tr>
<tr data-href="https://www.stackoverflow.com">
<td>One</td>
<td>Two</td>
<td>Three</td>
<td>Four</td>
<td>
Link
</td>
</tr>
</tbody>
</table>
You could give the row an id, e.g.
<tr id="special"> ... </tr>
and then use jquery to say something like:
$('#special').onclick(function(){ window="http://urltolinkto.com/x/y/z";})
Why should we don't use "div" tags....
<div>
<a href="" > <div> Table row of content here.. </div> </a>
</div>

How can you create two equaly wide elements, relative to the largest of the two, while keeping a flexible 'structure' using only html/css?

I've been trying to achieve the following using only html and css but I can't seem to get it right.
Consider the following image:
The image shows two desired outputs depending on their pseudo media queries min-width: X and max-width: X. It doesn't really matter what the media queries are, what is important is that the structure is able change so the output matches that of the image.
So what I've been struggling with is to have single-lined texts in the grey containers marked 'a' and have these containers have the same width relative to the largest of the two. The width of 'a' accomidate texts of variable lengths, not more not less. I also want 'a' to be lined out to the left as much as possible.
Remember I'm trying to accomplish this using only HTML and CSS.
Ended up solving my problem with using a table. The key lay in changing the display property of the td elements.
table {
width:300px;
background-color:#4192AD;
margin-bottom:30px;
}
td {
height:20px;
}
td:first-child{
width:1%;
white-space:nowrap;
text-align:right;
background-color:#C6C6C6;
}
td:nth-child(2) {
background-color:#73AD5A;
}
.alternate td {
display:block;
width:auto;
text-align:left;
}
<table>
<tbody>
<tr>
<td>short-text</td>
<td></td>
</tr>
<tr>
<td>relatively-long-text</td>
<td></td>
</tr>
</tbody>
</table>
<table class='alternate'>
<tbody>
<tr>
<td>short-text</td>
<td></td>
</tr>
<tr>
<td>relatively-long-text</td>
<td></td>
</tr>
</tbody>
</table>

how to make a whole row in a table clickable as a link?

I'm using Bootstrap and the following doesn't work:
<tbody>
<a href="#">
<tr>
<td>Blah Blah</td>
<td>1234567</td>
<td>£158,000</td>
</tr>
</a>
</tbody>
Author's note I:
Please look at other answers below, especially ones that do not use jquery.
Author's note II:
Preserved for posterity but surely the wrong approach in 2020. (Was non idiomatic even back in 2017)
Original Answer
You are using Bootstrap which means you are using jQuery :^), so one way to do it is:
<tbody>
<tr class='clickable-row' data-href='url://'>
<td>Blah Blah</td> <td>1234567</td> <td>£158,000</td>
</tr>
</tbody>
jQuery(document).ready(function($) {
$(".clickable-row").click(function() {
window.location = $(this).data("href");
});
});
Of course you don't have to use href or switch locations, you can do whatever you like in the click handler function. Read up on jQuery and how to write handlers;
Advantage of using a class over id is that you can apply the solution to multiple rows:
<tbody>
<tr class='clickable-row' data-href='url://link-for-first-row/'>
<td>Blah Blah</td> <td>1234567</td> <td>£158,000</td>
</tr>
<tr class='clickable-row' data-href='url://some-other-link/'>
<td>More money</td> <td>1234567</td> <td>£800,000</td>
</tr>
</tbody>
and your code base doesn't change. The same handler would take care of all the rows.
Another option
You can use Bootstrap jQuery callbacks like this (in a document.ready callback):
$("#container").on('click-row.bs.table', function (e, row, $element) {
window.location = $element.data('href');
});
This has the advantage of not being reset upon table sorting (which happens with the other option).
Note
Since this was posted window.document.location is obsolete (or deprecated at the very least) use window.location instead.
You can't do that. It is invalid HTML. You can't put a <a> in between a <tbody> and a <tr>. Try this instead:
<tr onclick="window.location='#';">
...
</tr>
add style for pointer view
[data-href] { cursor: pointer; }
When you work up to it, you'd want to use JavaScript to assign the click handler outside the HTML.
You could include an anchor inside every <td>, like so:
<tr>
<td>Blah Blah</td>
<td>1234567</td>
<td>more text</td>
</tr>
You could then use display:block; on the anchors to make the full row clickable.
tr:hover {
background: red;
}
td a {
display: block;
border: 1px solid black;
padding: 16px;
}
Example jsFiddle here.
This is probably about as optimum as you're going to get it unless you resort to JavaScript.
A linked table row is possible, but not with the standard <table> elements. You can do it using the display: table style properties. Here and here are some fiddles to demonstrate.
This code should do the trick:
.table {
display: table;
}
.row {
display: table-row;
}
.cell {
display: table-cell;
padding: 10px;
}
.row:hover {
background-color: #cccccc;
}
.cell:hover {
background-color: #e5e5e5;
}
<link href="https://stackpath.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet" type="text/css" />
<div role="grid" class="table">
<div role="row" class="row">
<div role="gridcell" class="cell">
1.1
</div>
<div role="gridcell" class="cell">
1.2
</div>
<div role="gridcell" class="cell">
1.3
</div>
</div>
<a role="row" class="row" href="#">
<div role="gridcell" class="cell">
2.1
</div>
<div role="gridcell" class="cell">
2.2
</div>
<div role="gridcell" class="cell">
2.3
</div>
</a>
</div>
Note that ARIA roles are needed to ensure proper accessibility since the standard <table> elements are not used. You may need to add additional roles like role="columnheader" if applicable. Find out more at the guide here.
Achieved using standard Bootstrap 4.3+ as follows - no jQuery nor any extra css classes needed!
The key is to use stretched-link on the text within the cell and defining <tr> as a containing block.
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"/>
<table class="table table-hover">
<tbody>
<tr style="transform: rotate(0);">
<th scope="row">1</th>
<td>Mark</td>
<td>Otto</td>
<td>#mdo</td>
</tr>
<tr>
<th scope="row">2</th>
<td>Jacob</td>
<td>Thornton</td>
<td>#fat</td>
</tr>
<tr>
<th scope="row">3</th>
<td>Larry</td>
<td>the Bird</td>
<td>#twitter</td>
</tr>
</tbody>
</table>
You can define containing block in different ways for example setting transform to not none value (as in example above).
For more information read here's the Bootstrap documentation for stretched-link.
A much more flexible solution is to target anything with the data-href attribute. This was you can reuse the code easily in different places.
<tbody>
<tr data-href="https://google.com">
<td>Col 1</td>
<td>Col 2</td>
</tr>
</tbody>
Then in your jQuery just target any element with that attribute:
jQuery(document).ready(function($) {
$('*[data-href]').on('click', function() {
window.location = $(this).data("href");
});
});
And don't forget to style your css:
[data-href] {
cursor: pointer;
}
Now you can add the data-href attribute to any element and it will work. When I write snippets like this I like them to be flexible. Feel free to add a vanilla js solution to this if you have one.
One solution that was not mentioned earlier is to use a single link in a cell and some CSS to extend this link over the cells:
table {
border: 1px solid;
width: 400px;
overflow: hidden;
}
tr:hover {
background: gray;
}
tr td {
border: 1px solid;
}
tr td:first-child {
position:relative;
}
a:before {
content: '';
position:absolute;
left: 0;
top: 0;
bottom: 0;
display: block;
width: 400px;
}
<table>
<tr>
<td>First column</td>
<td>Second column</td>
<td>Third column</td>
</tr>
<tr>
<td>First column</td>
<td>Second column</td>
<td>Third column</td>
</tr>
</table>
Here is simple solution..
<tr style='cursor: pointer; cursor: hand;' onclick="window.location='google.com';"></tr>
You can use this bootstrap component:
http://jasny.github.io/bootstrap/javascript/#rowlink
Jasny Bootstrap
The missing components for your favorite front-end framework.
<table class="table table-striped table-bordered table-hover">
<thead>
<tr><th>Name</th><th>Description</th><th>Actions</th></tr>
</thead>
<tbody data-link="row" class="rowlink">
<tr><td>Input mask</td><td>Input masks can be used to force the user to enter data conform a specific format.</td><td class="rowlink-skip">Action</td></tr>
<tr><td>jasny.net</td><td>Shared knowledge of Arnold Daniels aka Jasny.</td><td class="rowlink-skip">Action</td></tr>
<tr><td>Launch modal</td><td>Toggle a modal via JavaScript by clicking this row.</td><td class="rowlink-skip">Action</td></tr>
</tbody>
</table>
Usage
Via data attributes
Add class .rowlink and attribute data-link="row" to a <table> or <tbody> element. For other options append the name to data-, as in data-target="a.mainlink" A cell can be excluded by adding the .rowlink-skip class to the <td>.
Via JavaScript
Call the input mask via javascript:
$('tbody.rowlink').rowlink()
You can add the button role to a table row and Bootstrap will change the cursor without any css changes. I decided to use that role as a way to easily make any row clickable with very little code.
Html
<table class="table table-striped table-hover">
<tbody>
<tr role="button" data-href="#">
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
</tbody>
</table>
jQuery
$(function(){
$(".table").on("click", "tr[role=\"button\"]", function (e) {
window.location = $(this).data("href");
});
});
You can apply this same principle to add the button role to any tag.
There is a nice way to technically do it with <a> tag inside <tr>, which might be semantically incorrect (might give you a browser warning), but will work with no JavaScript/jQuery required:
<!-- HTML -->
<tbody>
<tr class="bs-table-row">
<td>Blah Blah</td>
<td>1234567</td>
<td>£158,000</td>
<a class="bs-row-link" href="/your-link-here"></a>
</tr>
</tbody>
/* CSS */
.bs-table-row {
position: 'relative';
}
.bs-row-link {
position: 'absolute';
left: 0;
height: '36px'; // or different row height based on your requirements
width: '100%';
cursor: 'pointer';
}
PS: Notice the trick here is to put <a> tag as last element, otherwise it will try to take the space of the first <td> cell.
PPS: Now your entire row will be clickable and you can use this link to open in new tab as well (Ctrl/CMD+click)
A very easy option is just use on-click, and more correct, in my point of view, because this separate the view and controller, and you don't need to hard code the URL or whatever more you need do accomplish with the click.
It works with Angular ng-click too.
<table>
<tr onclick="myFunction(this)">
<td>Click to show rowIndex</td>
</tr>
</table>
<script>
function myFunction(x) {
alert("Row index is: " + x.rowIndex);
}
</script>
Exemple working here
You can use onclick javascript method in tr and make it clickable, also if you need to build your link due to some details you can declare a function in javascript and call it in onclick, passing some values.
Here is a way by putting a transparent A element over the table rows. Advantages are:
is a real link element: on hover changes pointer, shows target link in status bar, can be keyboard navigated, can be opened in new tab or window, the URL can be copied, etc
the table looks the same as without the link added
no changes in table code itself
Disadvantages:
size of the A element must be set in a script, both on creation and after any changes to the size of the row it covers (otherwise it could be done with no JavaScript at all, which is still possible if the table size is also set in HTML or CSS)
The table stays as is:
<table id="tab1">
<tbody>
<tr>
<td>Blah Blah</td>
<td>1234567</td>
<td>£158,000</td>
</tr>
</tbody>
</table>
Add the links (for each row) via jQuery JavaScript by inserting an A element into each first column and setting the needed properties:
// v1, fixed for IE and Chrome
// v0, worked on Firefox only
// width needed for adjusting the width of the A element
var mywidth=$('#tab1').width();
$('#tab1 tbody>tr>td:nth-child(1)').each(function(index){
$(this).css('position', 'relative');// debug: .css('background-color', '#f11');
// insert the <A> element
var myA=$('<A>');
$(this).append(myA);
var myheight=$(this).height();
myA.css({//"border":'1px solid #2dd', border for debug only
'display': 'block',
'left': '0',
'top': '0',
'position': 'absolute'
})
.attr('href','the link here')
.width(mywidth)
.height(myheight)
;
});
The width and height setting can be tricky, if many paddings and margins are used, but in general a few pixels off should not even matter.
Live demo here: http://jsfiddle.net/qo0dx0oo/ (works in Firefox, but not IE or Chrome, there the link is positioned wrong)
Fixed for Chrome and IE (still works in FF too): http://jsfiddle.net/qo0dx0oo/2/
This code bellow will make your whole table clickable. Clicking the links in this example will show the link in an alert dialog instead of following the link.
The HTML:
Here's the HTML behind the above example:
<table id="example">
<tr>
<th> </th>
<th>Name</th>
<th>Description</th>
<th>Price</th>
</tr>
<tr>
<td>Edit</td>
<td>Apples</td>
<td>Blah blah blah blah</td>
<td>10.23</td>
</tr>
<tr>
<td>Edit</td>
<td>Bananas</td>
<td>Blah blah blah blah</td>
<td>11.45</td>
</tr>
<tr>
<td>Edit</td>
<td>Oranges</td>
<td>Blah blah blah blah</td>
<td>12.56</td>
</tr>
</table>
The CSS
And the CSS:
table#example {
border-collapse: collapse;
}
#example tr {
background-color: #eee;
border-top: 1px solid #fff;
}
#example tr:hover {
background-color: #ccc;
}
#example th {
background-color: #fff;
}
#example th, #example td {
padding: 3px 5px;
}
#example td:hover {
cursor: pointer;
}
The jQuery
And finally the jQuery which makes the magic happen:
$(document).ready(function() {
$('#example tr').click(function() {
var href = $(this).find("a").attr("href");
if(href) {
window.location = href;
}
});
});
What it does is when a row is clicked, a search is done for the href belonging to an anchor. If one is found, the window's location is set to that href.
I know someone has written pretty much the same already, however my way is the correct way (div cannot be child of A) and also it's better to use classes.
You can imitate a table using CSS and make an A element the row
<div class="table" style="width:100%;">
<a href="#" class="tr">
<span class="td">
cell 1
</span>
<span class="td">
cell 2
</span>
</a>
</div>
css:
.table{display:table;}
.tr{display:table-row;}
.td{display:table-cell;}
.tr:hover{background-color:#ccc;}
i would prefer to use onclick="" attribute as it is easy to use and understand for newbie like
<tr onclick="window.location='any-page.php'">
<td>UserName</td>
<td>Email</td>
<td>Address</td>
</tr>
Here's an article that explains how to approach doing this in 2020: https://www.robertcooper.me/table-row-links
The article explains 3 possible solutions:
Using JavaScript.
Wrapping all table cells with anchorm elements.
Using <div> elements instead of native HTML table elements in order to have tables rows as <a> elements.
The article goes into depth on how to implement each solution (with links to CodePens) and also considers edge cases, such as how to approach a situation where you want to add links inside you table cells (having nested <a> elements is not valid HTML, so you need to workaround that).
As #gameliela pointed out, it may also be worth trying to find an approach where you don't make your entire row a link, since it will simplify a lot of things. I do, however, think that it can be a good user experience to have an entire table row clickable as a link since it is convenient for the user to be able to click anywhere on a table to navigate to the corresponding page.
Another option using an <a>, CSS positions and some jQuery or JS:
HTML:
<table>
<tr>
<td>
<span>1</span>
</td>
<td><span>2</span></td>
</tr>
</table>
CSS:
table tr td:first-child {
position: relative;
}
a.rowLink {
position: absolute;
top: 0; left: 0;
height: 30px;
}
a.rowLink:hover {
background-color: #0679a6;
opacity: 0.1;
}
Then you need to give the a width, using for example jQuery:
$(function () {
var $table = $('table');
$links = $table.find('a.rowLink');
$(window).resize(function () {
$links.width($table.width());
});
$(window).trigger('resize');
});
The accepted answer is great, but I propose a small alternative if you don't want to repeat the url on every tr.
So you put the url or href in the table data-url and not the tr.
<table data-click data-url="href://blah">
<tbody>
<tr id ="2">
<td>Blah Blah</td> <td>1234567</td> <td>£158,000</td>
</tr>
<tr id ="3">
<td>Blah Blah</td> <td>1234567</td> <td>£158,000</td>
</tr>
</tbody>
</table
jQuery(document).ready(function($) {
$('[data-click] tbody tr').click(function() {
var url = $(this).closest('table').data("url");
var id = $(this).closest('tr').attr('id');
window.location = url+"?id="+id);
});
});
This is also good because you don't need to add the click data attribute to every tr either. The other good thing is that we are not using a class to trigger a click as classes should only really be used for styling.
<tbody>
<tr data-href='www.bbc.co.uk'>
<td>Blah Blah</td>
<td>1234567</td>
<td>£158,000</td>
</tr>
<tr data-href='www.google.com'>
<td>Blah Blah</td>
<td>1234567</td>
<td>£158,000</td>
</tr>
</tbody>
<script>
jQuery(document).ready(function ($) {
$('[data-href]').click(function () {
window.location = $(this).data("href");
});
});
</script>
Whilst the main solution on here is great, my solution removes the need for classes. All you need to do is add the data-href attribute with the URL in it.
I've invested a lot of time trying to solve this problem.
There are 3 approaches:
Use JavaScript. The clear drawbacks: it's not possible to open a new tab natively, and when hovering over the row there will be no indication on status bar like regular links have. Accessibility is also a question.
Use HTML/CSS only. This means putting <a> nested under each <td>. A simple approach like this fiddle doesn't work - Because the clickable surface is not necessarily equal for each column. This is a serious UX concern. Also, if you need a <button> on the row, it is not valid HTML to nest it under <a> tag (although browsers are ok with that).
I've found 3 other ways to implement this approach. First is ok, the other two are not great.
a) Have a look on this example:
tr {
height: 0;
}
td {
height: 0;
padding: 0;
}
/* A hack to overcome differences between Chrome and Firefox */
#-moz-document url-prefix() {
td {
height: 100%;
}
}
a {
display: block;
height: 100%;
}
It works, but due to inconsistencies between Chrome and Firefox it requires browser-specific hack to overcome the differences. Also Chrome will always align the cell content to the top, which can cause problems with long texts, especially if varying line heights are involved.
b) Setting <td> to { display: contents; }. This leads to 2 other problems:
b1. If someone else tries to style directly the <td> tag, like setting it to { width: 20px; }, we need to pass that style somehow to the <a> tag. We need some magic to do that, probably more magic than in the Javascript alternative.
b2. { display: contents; } is still experimental; specifically it's not supported on Edge.
c) Setting <td> to { height: --some-fixed-value; }. This is just not flexible enough.
The last approach, which I recommend to seriously thinking of, is to not using clickable rows at all. Clickable rows is not a great UX experience: it's not easy to visually mark them as clickable, and it poses challenges when multiple parts are clickable within the rows, like buttons. So a viable alternative could be to have an <a> tag only on the first column, displayed as a regular link, and give it the role of navigating the whole row.
Here's a generic approach. Define this css:
// css
td a.linker {
color:#212529;
display: block;
padding: 16px;
text-decoration: none;
}
Then place this inside each td:
<td>
<a class="linker" href="www.google.com">
Cell content goes here
</a>
</td>
Here is another way...
The HTML:
<table>
<tbody>
<tr class='clickableRow'>
<td>Blah Blah</td>
<td>1234567</td>
<td>£158,000</td>
</tr>
</tbody>
</table>
The jQuery:
$(function() {
$(".clickableRow").on("click", function() {
location.href="http://google.com";
});
});
<table>
<tr tabindex="0" onmousedown="window.location='#';">
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
</table>
Replace # with the url, tabindex="0" makes any element focusable
A 2023 answer:
You can add an addEventListener to the row:
var rows = document.getElementsByTagName('table')[0].rows;
Array.from(rows).forEach(row => {
row.addEventListener("click", function() {
console.log(this.getAttribute('data-href'));
// window.location.href = this.getAttribute('data-href');
});
});
body {
display: flex;
justify-content: center;
margin-top: 20px;
color: #37559d;
}
a {
color: #5165ff;
}
table {
border-collapse: collapse;
}
tr:hover {
background: #f2f3ff;
outline: none;
cursor: pointer;
}
td {
border: 2px solid #ccd2ff;
position: relative;
padding: 18px;
}
<table>
<tbody>
<tr data-href="https://www.google.com">
<td>One</td>
<td>Two</td>
<td>Three</td>
<td>Four</td>
<td>
Link
</td>
</tr>
<tr data-href="https://www.amazon.com">
<td>One</td>
<td>Two</td>
<td>Three</td>
<td>Four</td>
<td>
Link
</td>
</tr>
<tr data-href="https://www.stackoverflow.com">
<td>One</td>
<td>Two</td>
<td>Three</td>
<td>Four</td>
<td>
Link
</td>
</tr>
</tbody>
</table>
You could give the row an id, e.g.
<tr id="special"> ... </tr>
and then use jquery to say something like:
$('#special').onclick(function(){ window="http://urltolinkto.com/x/y/z";})
Why should we don't use "div" tags....
<div>
<a href="" > <div> Table row of content here.. </div> </a>
</div>

CSS in <body> part (without inline)

Is there a way to put some CSS into the BODY part of my html page without using inline CSS?
e.g.: I want to make all elements of one table red. Downside here: need same style=".." for every TD.
<table>
<tr>
<td style="background-color:#f00">RED</td>
<td style="background-color:#f00">RED</td>
</tr>
</table>
If you want all 'td' elements of one specific table with a specific css style, you should use this code:
html:
<table id="tableOne">
<tr>
<td>red background</td>
<td>red background</td>
</tr>
</table>
<table>
<tr>
<td>blank background</td>
<td>blank background</td>
</tr>
</table>
css:
#tableOne td{
background-color: #FF0000;
}
<table class="myClass">
<tr>
<td>RED</td>
<td>RED</td>
</tr>
</table>
And your css class myClass:
.myClass td
{
background: #F00;
}
To keep all the code within the body you could use javascript to first find all TD's then apply the background color:
<script>
var cells = document.getElementsByTagName("td");
for (var i=0; i<cells.length; i++) {
cells[i].style.backgroundColor = '#c0c0c0';
}
</script>
In an embedded or external style sheet:
td { background: #F00; }
That's all.

Link entire table row? [duplicate]

This question already has answers here:
how to make a whole row in a table clickable as a link?
(28 answers)
Closed 2 years ago.
I know it is possible to link an entire table cell with CSS.
.tableClass td a{
display: block;
}
Is there a way to apply a link to an entire table row?
I agree with Matti. Would be easy to do with some simple javascript. A quick jquery example would be something like this:
<tr>
<td>example</td>
<td>another cell</td>
<td>one more</td>
</tr>
and
$('tr').click( function() {
window.location = $(this).find('a').attr('href');
}).hover( function() {
$(this).toggleClass('hover');
});
then in your CSS
tr.hover {
cursor: pointer;
/* whatever other hover styles you want */
}
Use the ::before pseudo element. This way only you don't have to deal with Javascript or creating links for each cell. Using the following table structure
<table>
<tr>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
</tr>
</table>
all we have to do is create a block element spanning the entire width of the table using ::before on the desired link (.rowlink) in this case.
table {
position: relative;
}
.rowlink::before {
content: "";
display: block;
position: absolute;
left: 0;
width: 100%;
height: 1.5em; /* don't forget to set the height! */
}
demo
The ::before is highlighted in red in the demo so you can see what it's doing.
Unfortunately, no. Not with HTML and CSS. You need an a element to make a link, and you can't wrap an entire table row in one.
The closest you can get is linking every table cell. Personally I'd just link one cell and use JavaScript to make the rest clickable. It's good to have at least one cell that really looks like a link, underlined and all, for clarity anyways.
Here's a simple jQuery snippet to make all table rows with links clickable (it looks for the first link and "clicks" it)
$("table").on("click", "tr", function(e) {
if ($(e.target).is("a,input")) // anything else you don't want to trigger the click
return;
location.href = $(this).find("a").attr("href");
});
Example: http://xxjjnn.com/linktablerow.html
Link entire row:
<table>
<tr onclick="location.href='SomeWherrrreOverTheWebsiiiite.html'">**
<td> ...content... </td>
<td> ...content... </td>
...
</tr>
</table>
Iff you'd like to do highlight on mouseover for the entire row, then:
<table class="nogap">
<tr class="lovelyrow" onclick="location.href='SomeWherrrreOverTheWebsiiiite.html'">**
...
</tr>
</table>
with something like the following for css, which will remove the gap between the table cells and change the background on hover:
tr.lovelyrow{
background-color: hsl(0,0%,90%);
}
tr.lovelyrow:hover{
background-color: hsl(0,0%,40%);
cursor: pointer;
}
table.nogap{
border-collapse: collapse;
}
Iff you are using Rails 3.0.9 then you might find this example code useful:
Sea has many Fish, Fish has many Scales, here is snippet of app/view/fish/index.erb
<table>
<% #fishies.each do |fish| %>
<tr onclick="location.href='<%= sea_fish_scales_path(#sea, fish) %>'">
<td><%= fish.title %></td>
</tr>
<% end %>
</table>
with #fishies and #sea are defined in app/controllers/seas_controller.rb
Also it depends if you need to use a table element or not. You can imitate a table using CSS and make an A element the row
<div class="table" style="width:100%;">
<a href="#" class="tr">
<span class="td">
cell 1
</span>
<span class="td">
cell 2
</span>
</a>
</div>
css:
.table{display:table;}
.tr{display:table-row;}
.td{display:table-cell;}
.tr:hover{background-color:#ccc;}
I feel like the simplest solution is sans javascript and simply putting the link in each cell (provided you don't have massive gullies between your cells or really think border lines). Have your css:
.tableClass td a{
display: block;
}
and then add a link per cell:
<table class="tableClass">
<tr>
<td>Link name</td>
<td>Link description</td>
<td>Link somthing else</td>
</tr>
</table>
boring but clean.
To link the entire row, you need to define onclick function on your row, which is <tr>element and define a mouse hover in the CSS for tr element to make the mouse pointer to a typical click-hand in web:
In table:
<tr onclick="location.href='http://www.google.com'">
<td>blah</td>
<td>blah</td>
<td><strong>Text</strong></td>
</tr>
In related CSS:
tr:hover {
cursor: pointer;
}
I think this might be the simplest solution:
<tr onclick="location.href='http://www.mywebsite.com'" style="cursor: pointer">
<td>...</td>
<td>...</td>
</tr>
The cursor CSS property sets the type of cursor, if any, to show when
the mouse pointer is over an element.
The inline css defines that for that element the cursor will be formatted as a pointer, so you don't need the 'hover'.