Mouse over effect to highlight the crosshair on a table

My code currently enables a crosshair function, but I am looking for a way to limit the highlight effect only within the cursor (hover) area.

Instead of highlighting in a "cross" shape, I would like it to show a backward "L" shape. This means that the highlight would only extend down to row 2 and column 3, and up to row 3 and column 2 when hovering over a cell. Is this clear?

This is the CSS code I am using:

table {
    border-collapse: collapse;
    overflow: hidden;
    z-index: 1;
}
.permissions table,
th,
td {
    border: 2px solid #ccc;
    width:90px;
    height:90px;
    text-align:center;
    vertical-align:middle;
    font-size:13px;
}

td, th, .row, .col, .ff-fix {
    cursor: pointer;
    position: relative;
}

tr, col {
    border: 1px solid black;
}

td:hover {
    background-color:red;
}

td:hover:first-child {
    background-color:red;
}

td:hover:nth-child(3n) {
    background-color:red;
}

tr:last-child td:hover {
    background-color: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;        
}

Here is the HTML code:

<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>

Answer №1

Although this information is dated, you can find a method utilizing Javascript here. This approach is preferred because it allows for customizable backgrounds without the need for CSS workarounds.

HTML:

<table id="hoverTable">
  <thead>
    <th>Column1</th>
    <th>Column2</th>
    <th>Column3</th>
    <th>Column4</th>
  </thead>
  <tbody>
    <tr>
      <td>Item</td>
      <td>Item</td>
      <td>Item</td>
      <td>Item</td>
    </tr>
    <tr>
      <td>Item</td>
      <td>Item</td>
      <td>Item</td>
      <td>Item</td>
    </tr>
    <tr>
      <td>Item</td>
      <td>Item</td>
      <td>Item</td>
      <td>Item</td>
    </tr>
    <tr>
      <td>Item</td>
      <td>Item</td>
      <td>Item</td>
      <td>Item</td>
    </tr>
  </tbody>
</table>

SCSS:

body {
  background:grey;
}
.hoverHighlight {
  background-color:yellow !important;
  cursor:default;
}

#hoverTable {
  font-family:arial;
  border-spacing:0;
  border-collapse: collapse;
  th, td {
    border:2px solid black;
    text-align:center;
    padding:5px;
    margin:0;
  }
  th {
    background:#1167b1;
    color:white;
  }
  td {
    text-align:center;
    background:#d0efff;
  }
}

Javascript:

  window.addEventListener('load', function () {
    addHoverEventsAndClasses();
  })

  function toggleHighlight(element, trueOrFalse) {
    const currentRow = returnCurRow(element);
    const index = element.currentTarget.cellIndex;
    const table = document.getElementById('hoverTable').rows;
    for (var i = 0; i < table.length; i++) {
        const data = table[i];
        const cells = data.querySelectorAll(".cell");
        if(data.rowIndex === currentRow) {
            cells.forEach((td) => {
                trueOrFalse ? td.classList.add("hoverHighlight") : td.classList.remove("hoverHighlight");
            });
        }
        cells.forEach((cell) => {
            if(cell.cellIndex === index) {
                trueOrFalse ? cell.classList.add("hoverHighlight") : cell.classList.remove("hoverHighlight");
            }
        });
    }
};

function addHoverEventsAndClasses() {
    const mainTableTDs = document.querySelectorAll("#hoverTable td");
    const mainTableTRs = document.querySelectorAll("#hoverTable tr");
    //Dynamically add class names to each row and cell to target
    addClass(mainTableTDs, "cell");
    addClass(mainTableTRs, "row");
    mainTableTDs.forEach((td) => {
        td.addEventListener("mouseenter", highlightCol); 
        td.addEventListener("mouseleave", removeHighlightCol);
    });
}
//Helper function for adding highlight classes
function addClass(el, cl) {
    el.forEach((child) => {
        child.classList.add(cl);
    });
};
//Toggle highlight functions. Did it this way so multiple arguments could be passed
function highlightCol(e) {
    toggleHighlight(e, true);
}
function removeHighlightCol(e) {
    toggleHighlight(e, false);
}
//Grab the current row
const returnCurRow = (e) => {
    return e.currentTarget.parentElement.rowIndex;
}

Answer №2

By following the CSS logic, you can add a full-width ::before and a full-height ::after that will be displayed on top of the table. To change how they appear (such as a cross or a "backward L"), adjust the horizontal and vertical positioning accordingly.

To switch the highlighting to a "backward L", try replacing your td:hover::before and td:hover::after selectors with the code below. Note that the positioning is now determined by the right and bottom properties rather than the original left and top.

td:hover::before,
.row:hover::before,
.ff-fix:hover::before { 
  background-color: #ffa;
  content: '\00a0';  
  height: 100%;
  right: 90px;
  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;  
  bottom: 90px;
  width: 100%;
  z-index: -1;        
}

You can preview how this will look in this JSFiddle link.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The flex container cannot contain all of the content due to an

I am looking to implement a flexbox dropdown menu similar to this: https://i.sstatic.net/Cer9D.png After researching online, I found a simple dropdown menu example. However, I want to customize it using flexbox and its properties. The issue I encountered ...

Begin composing in Excel

I am looking to manipulate an existing Excel file by writing values from an array and closing it all on the client side. Here is the code snippet I have been using: for (var c=0; c<arrMCN.length; c++) { var mcnCreate = arrMCN[c]; var mcnNumber =mcnCre ...

Guide for utilizing the Primary Key in a Django context view to display data in an HTML template through a Python for loop

Within my views, I have the following method along with my HTML structure: def index(request): context = { "user": User.objects.get(id = request.session['user_id']), "book": Book.objects.all(), &qu ...

Using values from a select menu in a math calculation without including a decimal point

I am working with a dropdown menu that contains various values... <select id="number1a" onChange="Addition()"> <option value="0" selected>-</option> <option value="10">10</option> <option value="7.5">7.5</optio ...

Is it possible to maintain a fixed footer while utilizing async/ajax functions?

Looking for a reliable solution to have a fixed footer that adjusts based on the page content? I've tested multiple samples, but they all fall short when it comes to incorporating AJAX elements. Is there a fixed footer out there that truly works seaml ...

Utilizing ES6 Proxy leads to the occurrence of an error message stating "this is not a function" whenever a function call

As I ventured into the depths of ES6 Proxies, attempting to be a crafty developer, I found myself entangled in their complexities. My goal was to intercept any get or set operation on a property from a class I had written and ensure that they were stored e ...

"Enhance User Experience with Material UI Autocomplete feature that allows for multiple

I am encountering an issue with a material ui auto component that I am currently working on. The component's code looks like this: <Autocomplete multiple options={props.cats} defaultValue={editRequest? ...

What is the best way to update the color of an fa icon when an error message is displayed using PHP

I am facing an issue with my form where error messages are displayed on certain input fields. The error messages show up correctly, but I want to change the color of the "fa" icon in the field when its corresponding error message appears. My goal is to ma ...

Oops! Looks like there was an issue with assigning to a reference or variable: Error: Uncaught (in promise)

I seem to be struggling with an issue that I believe may have been addressed before, but after reviewing other solutions, I am unable to pinpoint the error in my code. Any assistance in identifying my mistake would be greatly appreciated. <div class="j ...

The operation of "grunt build" results in a Lexer Error, causing the ng-include

After deploying my unminified code successfully, I proceed to run grunt build and deploy from the dist folder. However, upon checking one of the pages, I encounter a breakage with an error in the console: Error: [$parse:lexerr] Lexer Error: Unexpected nex ...

Guide for dynamically populating Jqgrid Dropdown depending on another dropdown's data选择如何根

On my screen, I have two dropdowns. One is a standard Razor dropdown and the other is a Jqgrid dropdown. The code for the Razor dropdown looks like this: <div class="col-md-4"> <label for="" class="control-label">Loan Currency</ ...

iPhone has trouble accessing alternative forms of content

<object width="300" height="100" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"> <param value="5352f5c8e96c251fb9d79890f2294608.swf" name="movie"> <!--[if !IE]>--> <object width="300" height="100" data="5352f5c8e96 ...

Using the find() function in Mongoose allows the use of a variable as a model

Would it be feasible to employ a variable in place of the model name when using the find() function in mongoose? For instance, if my website is capable of displaying photos and videos based on the last part of the URL, which could be either /photo or /vide ...

Ongoing state configuration in a React hook

My custom hook: export function useToken2() { const { data: session, status } = useSession(); const [token, setToken] = useState<string | null>(null); useEffect(() => { if (status === 'authenticated' && session?.accessToken) { ...

Utilize a randomized dynamic base URL without a set pattern to display a variety of pages

I am intrigued by the idea of creating a dynamic route that can respond to user-generated requests with specific files, similar to how Github handles URLs such as www.github.com/username or www.github.com/project. These URLs do not follow a set pattern, ma ...

The CSS keyframe for mobile devices initiates from 100% and then proceeds to animate

Having some trouble with CSS animations on mobile devices. The animation works perfectly fine on desktop, but on mobile, it seems to display the final 100% keyframe first before animating from 0%. I've tried adding the initial style directly to the cl ...

What is the best way to customize the woocommerce.css file in the parent theme?

Currently, I have incorporated an ecommerce-friendly wordpress theme for my website in conjunction with woocommerce. To customize the design, I created a child theme and transferred the woocommerce.css file from the plugin into the css of the child theme, ...

Invoke the function when you finish typing in React.js

After I finish typing, I want to execute some code. I attempted to use the following script but it didn't work as expected const stopTypingHandler=(e)=>{ let time; clearTimeout(time); time = setTimeout(() => { console.log("click& ...

Unable to establish proper functionality of username variables in Node.js chat application

For my latest project, I am developing a chat application in node.js following a tutorial from socket.io. The main objective of the app is to allow users to input their username along with a message, which will then be displayed as "username: message" in t ...

Which is the Better Choice for an MMO WebSocket Server: Node.js or C++?

Contemplating creating a live game using WebSockets for the web has been on my mind. With my knowledge of Node.js, it's tempting to develop it there. However, C++ appears to be the favored server language due to its speed. Would it be best to try bui ...