Maze
Maze

Reputation: 452

CSS table tr hover one color/border and td hover another color/border without important

I have the following fiddle.

Edit: with row boarder style be applied:

table,th,td
{
    border:2px solid black;
    border-collapse:collapse;
}
tr:hover td
{
    background-color:grey;
    border-top: 2px solid rgb(10, 0, 255);
    border-bottom: 2px solid rgb(10, 0, 255);
}
td:hover
{
    background-color:rgb(214,214,214) !important;
    border:2px solid red !important;
    border-top: 2px solid red;
    border-bottom: 2px solid red;
}

What I'm after is highlighting the ROW and CELL. Originally had thought doing sort of cross-hair, but column background coloring would need JavaScript, which I'll avoid for the time being.

On this would like the ROW:hover background color darkish and border emphasized.

The td:hover then to be a different color, and border emphasized differently.

Checked in Chrome, not checked Firefox.

Issues: need to use !important. Cell border-left and top not coloring to red?

So is there a way to write the CSS not using important!, and correct border styling on the TD cell?

Upvotes: 5

Views: 19005

Answers (3)

Joy
Joy

Reputation: 9550

Here is a simpler solution: set the following style to all table, tr and td:

border: 2px inset black;
border-collapse: collapse;
border-spacing: 0;

Making border inset does the trick. inset is useful:

When both parent and child elements have borders, with this technique you don't get two borders (which looks ugly). This is because child elements are rendered over inset box shadows, not inside inset box shadows.

Reference: http://makandracards.com/makandra/12019-css-emulate-borders-with-inset-box-shadows

Working examples: http://jsfiddle.net/TR8Zg/146/

It is working well on Chrome. But on IE and FireFox the inset effect is populated. So need to find some fixes on them.

Upvotes: 1

ThinkingStiff
ThinkingStiff

Reputation: 65341

You can do your original crosshairs idea with just CSS (no Javascript). Use the ::before and ::after pseudo-elements for highlighting. There's a slight issue with Firefox with this method, so I wrote a fix for it.

border-collapse: collapse makes borders on <tds> behave in strange ways. Instead, put your borders on the <trs> and <cols>. border-collapse: collapse also cuts off edges. To deal with that you have to get creative and draw an extra border on all the outside <tds> and <ths>. Even stranger, it "eats" a pixel on the top and two pixels on the bottom. So you need 3px on top to get a 2px border, and 4px on bottom to get a 2px border.

Demo: jsFiddle

CSS:

table {
    border-collapse: collapse;
    overflow: hidden;
    z-index: 1;
}
td, th, .row, .col, .ff-fix {
    cursor: pointer;
    padding: 10px;
    position: relative;
}
tr:last-child td {
    border-bottom: 4px solid black;
}
tr, col {
    border: 2px solid black;
}
th {
    border-top: 3px solid black;
}
th:last-child, td:nth-child(3n) {
    border-right: 4px solid black;
}
td:first-child, th:first-child {
    border-left: 3px solid black;
}
td:hover {
    border: 2px solid red;
}
td:hover:first-child {
    border-left: 3px solid red;
}
td:hover:nth-child(3n) {
    border-right: 4px solid red;
}
tr:last-child td:hover {
    border-bottom: 4px solid red;
}
td:hover::before,
.row:hover::before,
.ff-fix:hover::before { 
    background-color: #ffa;
    content: '\00a0';  
    height: 100%;
    left: -5000px;
    position: absolute;  
    top: 0;
    width: 10000px;   
    z-index: -1;   
}
td:hover::after,
.col:hover::after,
.ff-fix:hover::after { 
    background-color: #ffa;
    content: '\00a0';  
    height: 10000px;    
    left: 0;
    position: absolute;  
    top: -5000px;
    width: 100%;
    z-index: -1;        
}

HTML:

<table>
    <col /><col /><col />
    <tr>
        <th class="col">First Name</th>
        <th class="col">Middle Name</th>
        <th class="col">Last Name</th>
    </tr>
    <tr>
        <td>Peter</td>
        <td>Jeffery</td>
        <td>Griffin</td>
    </tr>
    <tr>
        <td>Lois</td>
        <td>Marie</td>
        <td>Griffin</td>
    </tr>
    <tr>
        <td>Margie</td>
        <td>Ann</td>
        <td>Thatcher</td>
    </tr>
</table>

Script:

function firefoxFix() {
    if ( /firefox/.test( window.navigator.userAgent.toLowerCase() ) ) {
        var tds = document.getElementsByTagName( 'td' ),
            ths = document.getElementsByTagName( 'th' );
        for( var index = 0; index < tds.length; index++ ) {
            tds[index].innerHTML = '<div class="ff-fix">' + tds[index].innerHTML + '</div>';                     
        };
        for( var index = 0; index < ths.length; index++ ) {
            ths[index].innerHTML = 
                  '<div class="' + ths[index].className + '">' 
                + ths[index].innerHTML 
                + '</div>';                     
            ths[index].className = '';
        };
        var style = '<style>'
            + 'td, th { padding: 0 !important; }' 
            + 'td:hover::before, td:hover::after { background-color: transparent !important; }'
            + '</style>';
        document.head.insertAdjacentHTML( 'beforeEnd', style );
    };
};

firefoxFix();

Upvotes: 3

Morpheus
Morpheus

Reputation: 9065

Your example works fine and you don't need to use !important. Remove border-collapse: collapse and you'll see(jsfiddle).

Upvotes: 1

Related Questions