Floating above a surface to manipulate a title

Wondering if it's possible to achieve this without JavaScript, but that would be the ideal scenario.

Here's a snapshot of how my page is structured:

 ____________________________
| TITLE                      |     |This is a fixed header. I want the title
|----------------------------|     |to be the name of the row and display it
|   _______    _______    ___|     |upon hovering over the image rows.
|  |       |  |       |  |   |     |
|  |       |  |       |  |   |     |
|  |_______|  |_______|  |___|     | [The boxes represent images.]
|   _______    _______    ___|     |
|__|_______|__|_______|__|___|     |

header {
  background: #FFFFFF;
  position: fixed !important;
  width: 100%;
  height: 85px;
  top: 0;
  left: 0;
  text-align: left;
  font-size: 30px;
  border: 1px solid black;
}

body {
  padding-top: 100px;
}

r1n {
  width: 200px;
  height: 200px;
  display: inline;
}

r1n:hover {
  display: none
}

table tr:hover ~ header r1n {
  display: none
}
<header>
  <r1n>TITLE_NAME</r1n>
</header>

<body>
  <table>
    <tr>
      <td>a</td>
      <td>b</td>
      <td>c</td>
      <td>d</td>
    </tr>
    <tr>
      <td>a</td>
      <td>b</td>
      <td>c</td>
      <td>d</td>
    </tr>
    <tr>
      <td>a</td>
      <td>b</td>
      <td>c</td>
      <td>d</td>
    </tr>
    <tr>
      <td>a</td>
      <td>b</td>
      <td>c</td>
      <td>d</td>
    </tr>
  </table>
</body>

Can the fixed header in CSS display the row's name when hovered over by leveraging divs in the header?

EDIT:

@AndrewBone and @Dekel came up with CSS and JS solutions, respectively

EDIT^2: Check out all the responses for good CSS/JS/jQuery solutions.

Answer №1

Many individuals argue that this method is not feasible, but I want to clarify that it can be done, although I would not recommend its practical use.

Consider the following example:

body {
  margin: 0;
}
table {
  margin: 18px 0 0 0;
  position: relative;
  border: 1px solid black;
}
tr:nth-child(even) {
  background: #DDD;
}
tr:nth-child(odd) {
  background: #FFF;
}
tr:hover {
  background: tomato;
}
tr[data-header]:hover:after {
  content: attr(data-header);
  position: absolute;
  top: -19px;
  left: -1px;
  border: 1px solid black;
  border-bottom-width: 0px;
  width: 100%;
}
td {
  padding: 5px 15px;
}
<table>
  <tr data-header="Header 1">
    <td>a</td>
    <td>b</td>
    <td>c</td>
    <td>d</td>
  </tr>
  <tr data-header="Header 2">
    <td>a</td>
    <td>b</td>
    <td>c</td>
    <td>d</td>
  </tr>
  <tr data-header="Header 3">
    <td>a</td>
    <td>b</td>
    <td>c</td>
    <td>d</td>
  </tr>
  <tr data-header="Header 4">
    <td>a</td>
    <td>b</td>
    <td>c</td>
    <td>d</td>
  </tr>
</table>

I have assigned a header attribute to each tr, and also included a pseudo element. This pseudo element inserts some content, sourced from the header attribute using attr(header). This positions the content within the parent element, table. Thus, we have functional code that operates without JavaScript. However, I recommend utilizing JavaScript whenever possible. :-)

I hope this explanation is helpful.

EDIT:

Below is a pure javascript solution

const trSel = document.querySelectorAll("tr[data-header]");
for (let i = 0; i < trSel.length; i++) {
  trSel[i].addEventListener("mouseover", function(evt) {
    let headSel = trSel[i].parentElement.parentElement.parentElement.querySelector(":scope > .header");
    headSel.innerHTML = trSel[i].dataset.header;
  });
}
body {
  margin: 0;
}
.header {
  padding: 5px 0;
}
tr:nth-child(even) {
  background: #DDD;
}
tr:nth-child(odd) {
  background: #FFF;
}
tr[data-header]:hover {
  background: tomato;
}
td {
  padding: 5px 15px;
}
<div>
  <div class="header">
    Placeholder!
  </div>
  <table>
    <tr data-header="Table 1 Row 1">
      <td>a</td>
      <td>b</td>
      <td>c</td>
      <td>d</td>
    </tr>
    <tr data-header="Table 1 Row 2">
      <td>a</td>
      <td>b</td>
      <td>c</td>
      <td>d</td>
    </tr>
    <tr data-header="Table 1 Row 3">
      <td>a</td>
      <td>b</td>
      <td>c</td>
      <td>d</td>
    </tr>
    <tr data-header="Table 1 Row 4">
      <td>a</td>
      <td>b</td>
      <td>c</td>
      <td>d</td>
    </tr>
  </table>
</div>

<h2>
Second table on the loose
</h2>

<div>
  <div class="header">
    Placeholder!
  </div>
  <table>
    <tr data-header="Table 2 Row 1">
      <td>a</td>
      <td>b</td>
      <td>c</td>
      <td>d</td>
    </tr>
    <tr data-header="Table 2 Row 2">
      <td>a</td>
      <td>b</td>
      <td>c</td>
      <td>d</td>
    </tr>
    <tr data-header="Table 2 Row 3">
      <td>a</td>
      <td>b</td>
      <td>c</td>
      <td>d</td>
    </tr>
    <tr data-header="Table 2 Row 4">
      <td>a</td>
      <td>b</td>
      <td>c</td>
      <td>d</td>
    </tr>
  </table>
</div>

The approach maintains the same principles, but now includes text updating, ensuring that the last selected row remains visible after mouse movement. This functionality extends to multiple tables as well.

EDIT 2: A slight modification has been made, switching to the usage of data-header instead of header, in alignment with best practices. ;-)

Answer №2

Just because you requested a javascript solution in response to @AndrewBone's answer.

Take note of how index is used to determine the current position of the hovered tr within the table. The index starts at 0, which is why you see +1 there.

$(function() {
  $('#tbl1 tr').hover(function() {
    i = $('#tbl1 tr').index(this) + 1;
    $('r1n').text('Row ' + i);
  });
});
header {
  background: #FFFFFF;
  position: fixed !important;
  width: 100%;
  height: 85px;
  top: 0;
  left: 0;
  text-align: left;
  font-size: 30px;
  border: 1px solid black;
}

body {
  padding-top: 100px;
  /*equal to the height of your header */
}

r1n {
  width: 200px;
  height: 200px;
  display: inline;
}
#tbl1 {
  border-collapse: collapse;
}
#tbl1 td {
  padding: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header>
  <r1n>TITLE_NAME</r1n>
</header>

<table id="tbl1" border="1">
  <tr>
    <td>a</td>
    <td>b</td>
    <td>c</td>
    <td>d</td>
  </tr>
  <tr>
    <td>a</td>
    <td>b</td>
    <td>c</td>
    <td>d</td>
  </tr>
  <tr>
    <td>a</td>
    <td>b</td>
    <td>c</td>
    <td>d</td>
  </tr>
  <tr>
    <td>a</td>
    <td>b</td>
    <td>c</td>
    <td>d</td>
  </tr>
</table>

Answer №3

Upon observing that there are existing answers (including an accepted one), I wanted to provide a jQuery solution with targets for those who may prefer this approach. It doesn't hurt to have another option available.

In the following code snippet, the table and header elements are considered siblings. Even though in the posted code, the body is the parent of the table and a sibling with the header. Here, everything is automatically inserted inside the default <body> tag.

$("table tr").hover(function(){
   var data = $(this).attr('data-target'),
       target = $(this).parents('table').siblings('header').find('h1')
       $(target).each(function(){
             if($(this).attr('id') == data) {
             $(this).toggle()
             }
  
       })
})
header {
  background: #FFFFFF;
  position: fixed !important;
  width: 100%;
  height: 85px;
  top: 0;
  left: 0;
  text-align: left;
  font-size: 30px;
  border: 1px solid black;
}

body {
  padding-top: 100px;
  /*equal to the height of your header */
}

header h1 {
  display:none;
  position:absolute;
  left:0;
  top:0;
  margin:0;
}


table tr {
  cursor:pointer;
  background:blue;

}
table tr:nth-child(odd) {
    background:red;
}
table,td { 
  border-collapse:collapse;
  padding:20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header>

  <h1 id="row1">Title row1 </h1>
  <h1 id="row2">Title row2 </h1>
  <h1 id="row3">Title row3 </h1>
  <h1 id="row4">Title row4 </h1>
</header>

<body>
  <table>
    <tr data-target="row1">
      <td>a</td>
      <td>b</td>
      <td>c</td>
      <td>d</td>
    </tr>
     <tr data-target="row2">
      <td>a</td>
      <td>b</td>
      <td>c</td>
      <td>d</td>
    </tr>
    <tr data-target="row3">
      <td>a</td>
      <td>b</td>
      <td>c</td>
      <td>d</td>
    </tr>
    <tr data-target="row4">
      <td>a</td>
      <td>b</td>
      <td>c</td>
      <td>d</td>
    </tr>
  </table>
</body>

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

What is the reason behind the success of chaining $q.when and $q.reject in Angular.js?

Why does this code not trigger the error callback when using $q in Angular.js: $q.when("test") .then($q.reject("error")) .then( function(v) { $scope.result = "Success: " + v; }, function(e) { $scope.result = "Failure: " ...

What is the best way to show distinct items and their frequencies from an array of objects in Vue.js/JavaScript?

I have been developing an inventory management application using Vuejs, and I am facing a JavaScript-related challenge in my project. The issue revolves around handling data that includes user information retrieved from a form, as well as static categories ...

What can I do to prevent the border from breaking apart when I zoom in?

To address the problem of the 1px black border at the bottom of the header being cut off, try zooming into the page and scrolling right. How can this issue be resolved? ...

Utilizing HTML5/JavaScript to send a text message from a mobile device

I am developing a mobile web application to be downloaded from various markets with a mini web server, capable of running on any operating system such as iOS, Android, Windows8, and more. My goal is to make the application as OS-independent as possible by ...

Instruction to pay attention to the event

After noticing that I've added similar event listening code to many of my controllers, I began to think about how to streamline it. The code looks something like this: document.addEventListener("resume", function(e){ $scope.doSomething(); }, ...

integrating an array into MongoDB using Angular and NodeJS

Encountering an issue with mlab (mongoose), angular.js, HTML, and JavaScript. When passing an array with values from an angular.js controller to the server side (node.js), it fails to insert the data into the schema in mlab. Below is my HTML code: <fo ...

"Sending a file (Image) through NextJS API Routes to an external API: A step-by-step guide

I am currently using a combination of NextJS (SSR and SPA for authorized dashboard) with Django Rest FW on the backend. To handle authentication, I employ JWT tokens stored in cookies. As a result, it is necessary to have a middleware at /pages/api/* that ...

Warning: Angular JS encountered a [$injector:modulerr] error

I'm currently working on developing an application using the MEAN stack. Here is a snippet of my controller code: var myApp = angular.module('myApp',[]); myApp.controller('AppCtrl',['$scope', '$http', function( ...

The width of Material UI Grid decreases every time it is re-rendered

I'm attempting to display a list of 25 words in a 5x5 grid using the MUI Grid component. The grid is structured as a <Grid container direction="column"> with five <Grid item> elements. Each <Grid item> contains: <Grid co ...

Android experiencing issues with dynamically loading Border XML

I am having trouble setting a border dynamically for a RelativeLayout. Oddly enough, when I manually add the border in the activity XML file, it displays perfectly. However, when I try to generate the border dynamically, it doesn't appear. border.xml ...

Changing a class using JavaScript: Adding and removing class dynamics

Currently, I am attempting to create a function that will toggle the visibility of a visual object on and off whenever the user clicks on it. Additionally, I need to implement a click event listener within the HTML class named btn-sauce. Unfortunately, my ...

Unexpected Disconnection of AJAX Response Moments Before Rebooting the Raspberry Pi

I currently have a LAMP server set up on my Raspberry Pi 4, where a web page is utilizing an AJAX call to trigger a php script that initiates a reboot of the pi. The php script echoes a JSON string response back to the web page indicating that it is prepar ...

Troubleshooting: How can I ensure my custom scrollbar updates when jQuery niceselect expands?

I am currently utilizing the jquery plugins mCustomScrollbar and niceselect. However, I have encountered an issue when expanding the niceselect dropdown by clicking on it - the mCustomScrollbar does not update accordingly. I suspect this is due to the abso ...

Include an item in a Vuetify model's array of objects

Currently, I am attempting to store the value of a dynamically loaded radio button into an array of objects. These radio buttons serve as options for a set of questions within a form, and my desired output is as follows: [{"question1":{ " ...

Save the output of a knex query to a variable

I'm struggling to assign the result of a select query using Knexjs to a variable. Here is my code: function getAllCategories() { let categories; categories = database.from("categories").select("category").then(function (rows) { for (let row of ro ...

Choose all pseudo elements from elements belonging to the class or ID labeled as 'x'

I am seeking a solution to target all the pseudo elements of an element that carries the class galleryBlock, as well as a method to target all the pseudo elements of an element with a specific id. My code structure consists of a grid made up of multiple i ...

Change the Vue3 PrimeVue theme or CSS file with a simple click or upon page load

One way to incorporate themes is by importing them in the main.js file at the root of the app: import 'primevue/resources/themes/arya-orange/theme.css'; However, I am exploring ways to dynamically switch CSS files based on the user's system ...

Adjust the height of a div vertically in Angular 2+

Recently, I started using angular2 and I've been attempting to create a vertically resizable div without success. I have experimented with a directive for this purpose. Below is the code for my directive: import { Directive, HostListener, ElementRef ...

What methods are available in JavaScript regex for validating city names?

var cityRegex = /^[a-zA-z] ?([a-zA-z]|[a-zA-z] )*[a-zA-z]$/; is the regular expression I attempted to create. However, it fails when inputting a city name like "St. Petersburg." Update: It seems challenging to create a perfect regex pattern for city name ...

Building a Backbone Model by utilizing JSON information that was received

Is there a way to create a backbone model using data received from a web service, rather than manually inputting the information? Imagine you're getting JSON data from a webservice, and you'd like to directly use this JSON as a backbone model. H ...