Tips for preventing a table from showing up while scrolling unnecessarily when utilizing a heading with the CSS position property set to 'sticky'

Currently, I am facing an issue with creating a sticky header for my table. The problem arises when the header of the table has rounded edges (top right and top left) along with a box-shadow applied to the entire table. As the user scrolls through the table, the box-shadow also moves, causing a visible gap between the header and the beginning of the table.

To provide better context, please refer to this video demonstration showcasing the mentioned issues.

The structure of my simple header is defined in Header.jsx:

 import { styles } from "../DataTablesStyles";

 export default function Header() {
    return (
        <TableHead sx={{position: 'sticky',top: '0px',zIndex: '1'}}>
            <TableRow >
                <TableCell style={styles.TableHeaderStyleFirst}>Actions</TableCell>
                <TableCell style={styles.TableHeaderStyle}>Status</TableCell>
                <TableCell style={styles.TableHeaderStyle}>Device ID</TableCell>
                <TableCell style={styles.TableHeaderStyle}>Model</TableCell>
                <TableCell style={styles.TableHeaderStyle}>Operation<br></br>System</TableCell>
                <TableCell style={styles.TableHeaderStyle}>Api<br></br>level</TableCell>
                <TableCell style={styles.TableHeaderStyle}>Last activity</TableCell>
                <TableCell style={styles.TableHeaderStyleLast}></TableCell>
            </TableRow>
        </TableHead>
    );
}

In DataTablesStyles.js, the styling for the table and headers is specified:

// In TableStyle I define the style of the whole table
const TableStyle = {
    borderTopRightRadius: '8px',
    borderTopLeftRadius: '8px',
    alignItems: 'center',
    justifyContent: "flex-end",
    padding: '16px',
    minWidth: '750px',
    boxShadow: '0px 0px 10px 0.1px rgba(124, 159, 236, 0.3)',
}

const TableHeaderStyle = {
    fontWeight: '400',
    fontSize: '14px',
    letterSpacing: '0.4px',
    color: 'black',
    backgroundColor: '#EAECF4',
    textAlign: 'center',
    padding: '2px',
}

const TableHeaderStyleFirst = {
    borderTopLeftRadius: '8px',
    fontWeight: '400',
    fontSize: '14px',
    letterSpacing: '0.4px',
    color: 'black',
    backgroundColor: '#EAECF4',
    textAlign: 'center',
    padding: '2px',

}

const TableHeaderStyleLast = {
    borderTopRightRadius: '8px',
    fontWeight: '400',
    fontSize: '14px',
    letterSpacing: '0.4px',
    color: 'black',
    backgroundColor: '#EAECF4',
    borderTopRightRadius: '8px',
    textAlign: 'center',
    padding: '2px',
}

If you grasp the gist of my query, how can I prevent the scrolling behavior of the shadow and eliminate the visible gap?

Answer №1

To achieve the desired result, I have implemented some changes. Firstly, it is important to note that the scrollbar should be exclusively on the table body and not affect the header section. Placing the scrollbar solely on the content area ensures a clean separation between the scrollable content and the fixed header.

https://i.stack.imgur.com/LGVkr.gif

Several additional class names were introduced to accommodate this adjustment. Working with tables can be quite intricate due to its historical roots in HTML, often requiring clever CSS tricks to properly layout rows and headers using techniques like display: table. For instance, setting the display of the tbody to block while maintaining the overall table structure intact demanded careful tweaking.

Now, you have control over the height through the .TableBodyStyle class, currently set at 400px for demonstration purposes.

Additionally, here is a codesandbox link for your reference: https://codesandbox.io/s/awesome-brook-i88vim

DevicesTable:

import { Table, TableBody, TableContainer } from "@mui/material";
import DevicesTableHeader from "./DevicesTableHeader";
import DevicesTableCell from "./DevicesTableCell";

export default function DevicesTable() {
  return (
    <TableContainer className="TableContainerGridStyle">
      <Table className="TableStyle">
        <DevicesTableHeader />
        <TableBody className="TableBodyStyle">
          <DevicesTableCell />
          <DevicesTableCell />
          <DevicesTableCell />
          <DevicesTableCell />
          <DevicesTableCell />
          <DevicesTableCell />
          <DevicesTableCell />
          <DevicesTableCell />
          <DevicesTableCell />
          <DevicesTableCell />
        </TableBody>
      </Table>
    </TableContainer>
  );
}

DevicesTableCell:

import React from "react";
import { TableCell, TableRow } from "@mui/material";
import "./DataTablesStyles.css";

export default function DevicesTableCell() {
  return (
    <TableRow className="TableCellStyle">
      <TableCell>Some Text</TableCell>
      <TableCell>Some Text</TableCell>
      <TableCell>Some Text</TableCell>
      <TableCell>Some Text</TableCell>
      <TableCell>Some Text</TableCell>
      <TableCell>Some Text</TableCell>
      <TableCell>Some Text</TableCell>
      <TableCell>Some Text</TableCell>
    </TableRow>
  );
}

DevicesTableHeader:

import "./DataTablesStyles.css";
import { TableCell, TableHead, TableRow } from "@mui/material";

export default function DevicesTableHeader() {
  return (
    <TableHead
      sx={{
        display: "table",
        tableLayout: "fixed",
        width: "100%"
      }}
    >
      <TableRow className="TableRowStyle">
        <TableCell className="TableHeaderStyle">Actions</TableCell>
        <TableCell className="TableHeaderStyle">Status</TableCell>
        <TableCell className="TableHeaderStyle">Device ID</TableCell>
        <TableCell className="TableHeaderStyle">Model</TableCell>
        <TableCell className="TableHeaderStyle">
          Operation<br></br>System
        </TableCell>
        <TableCell className="TableHeaderStyle">
          Api<br></br>level
        </TableCell>
        <TableCell className="TableHeaderStyle">Last activity</TableCell>
        <TableCell className="TableHeaderStyle"></TableCell>
      </TableRow>
    </TableHead>
  );
}

The CSS:

.TableContainerGridStyle {
  overflow: visible !important;
}

.TableStyle {
  display: block;
  border-top-left-radius: 8px;
  border-top-right-radius: 8px;
  align-items: center;
  justify-content: flex-end;
  min-width: 750px;
  box-shadow: 0px 0px 10px 0.1px rgba(124, 159, 236, 0.3);
}

.TableHeaderStyle {
  font-weight: 400;
  font-size: 14px;
  letter-spacing: 0.4px;
  color: black;
  background-color: #eaecf4;
  padding: 2px 16px;
}

.TableHeaderStyle:first-child {
  border-top-left-radius: 8px;
  padding: 2px 16px;
}

.TableHeaderStyle:last-child {
  border-top-right-radius: 8px;
  padding: 2px 25px 2px 22px;
}

.TableCellStyle {
  border-top: 2px solid #eaecf4;
  border-bottom: 1.1px solid #eaecf4;
  background-color: #ffffff;
  display: table;
  table-layout: fixed;
  width: 100%;
}

tr.TableCellStyle {
  display: table;
}

.TableCellStyle td:last-child {
  padding-right: 22px;
}

.TableBodyStyle {
  display: block !important;
  overflow: overlay;
  table-layout: fixed;
  max-height: 400px;
}

.TableBodyStyle tr:first-child {
  border-top: 0;
}

.TableBodyStyle tr:last-child {
  border-bottom: 0;
}

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

Converting JavaScript variable values to PHP variables by extracting the content of a textarea

Currently, I'm developing a data filtering mask which triggers when the button <input type="button" /> is clicked. In this process, I have: School classes (1, 2, 3, 4, 5) Sections (A, B, C....Z) Checkboxes for male and female sexes. This ma ...

Form a bond with the latest SignalR library to initiate communication

After attempting to connect to an asp.net core signalR server using the code below, I encountered some issues. Can you spot where I might have gone wrong? Here is the error message that I received: Error: The "promise" option must be a Promise v ...

What is the best way to halt a jQuery function when hovering over it?

Currently, I have a jQuery function set up to run on setInterval(). However, I am looking for a way to pause the interval when hovering over the displayed div and then resume once no longer hovering (i.e., continue cycling through the divs). Does anyone ...

Minimize the visibility of the variable on a larger scale

I have a nodejs app where I define global variables shared across multiple files. For example: //common.js async = requires("async"); isAuthenticated = function() { //... return false; }; //run.js require("common.js"); async.series([function () { i ...

I desire to perform a specific task when there is a modification in the path using react router framework

Though I am mindful of it. props.history.listen((location, action) => { console.log("when route changes",location); }) However, I need to implement it in a slightly different way. For instance, let's cons ...

Connection to external sources has been deactivated

I am experiencing an issue on my website at . When attempting to click on a link, it seems to be disabled. I suspect this is due to the presence of two images at the end of the navigation bar. Removing these images causes the navigation bar to fall apart, ...

What is the best way to showcase data from a JSON file in my React application?

This code snippet is for the Transactions page where I am connecting all data and defining the data to be displayed. import React, { useEffect, useState } from "react"; import { DataGrid } from "@mui/x-data-grid"; import axios from &quo ...

Guide to adding table classes to AJAX response tables

I am facing an issue with displaying data in a table based on the AJAX request made. The problem arises because the data displayed does not follow the pagination classes applied to the table. My table has pagination functionality where 10 records are shown ...

Setting up NextJS on Vercel for website deployment can encounter a common error known as ENOENT Error, which is caused by the absence of a specific file or

Everything works perfectly on my local machine: import fs from 'fs' import path from 'path' export default function createNewDirectory (tokenSignature: string) { const directoryPath = path.join(process.cwd(), 'notes', to ...

NodeJS: Steps to efficiently transfer data from a master table to two separate tables while maintaining the order of the master table, utilizing asynchronous code wherever applicable

Are promises or async/await being used for this task? For instance: if the master table has columns (id, uuid, op_1, op_2) then the new tables should be table1(id, uuid) table2(id, op_1, op_2) The priority is to maintain the same order as the master ta ...

Move the divs within the overflow container by sliding them, then take out the initial element and append it to the end

Currently, when I utilize .appendTo(".wrapper") as shown in the code below, it eliminates the animation effect. My goal is to have the div on the far left slide out of view, triggering an overflow hidden effect, and then be placed at the end of the slide c ...

Updating an element's HTML content from a template URL using AngularJS

Can someone help me figure out how to set the html of an element in my directive based on a dynamic template url? element.html('some url to a template html file'); rather than using element.html('<div>test</div>').show() ...

Console displaying a 400 bad request error for an HTTP PUT request

I'm currently in the process of developing a react CRUD application using Strapi as the REST API. Everything is working smoothly with the GET, DELETE, and CREATE requests, but I encounter a 400 bad request error when attempting to make a PUT request. ...

"Utilizing Bootstrap to ensure content is aligned perfectly to the baseline

I've been struggling to align my contents to the baseline while working with the bootstrap framework. I tried following the instructions in the documentation, but it didn't work out as expected. <div class="row"> <div class="col-12 ...

Using the v-for directive to loop through a list of items and adding a v-autocomplete with

I am facing a challenge with using a dropdown menu within a loop to select the region for each office in my list of offices. The problem lies in passing the index value to the updateRegion method so that I can correctly associate the selected region with t ...

How is it possible to encounter a Javascript unexpected token ] error within an HTML code?

While working on my project, I encountered a JavaScript error in the console of Chrome. The error message stated "Unexpected token ]" and it was pointing to a specific line of raw HTML code. I am puzzled about what could be causing this issue. Unfortunatel ...

"Troubleshooting: Issues with functionality of React basic list in class components

Just started learning React and following the steps outlined in this page: https://facebook.github.io/react/docs/lists-and-keys.html I currently have two components: App.js var React = require('react'); var NumberList = require('./NumberL ...

Change the visibility of a div's content when a radio button is selected with only CSS

When the radio buttons are on the same div level as "content1" and "content2", it works properly. But how can I make it work if I move the radio buttons to another div outside of the "second" div? For example, if toggle1 is checked then content1 should be ...

In Chrome, the `Jquery $('input[name=""]').change(function will not be triggered unless there is an unhandled error following it

Here is a script that I've created to make certain inputs dependent on the selection of a radio button. The 'parent' input in this case is determined by the radio button choice. Upon document load, the script initially hides parent divs of ...

What is the best way to display two arrays next to each other in an Angular template?

bolded text I am struggling to display two arrays side by side in an angular template. I attempted to use ngFor inside a div and span but the result was not as expected. A=[1,2,3,4] B=[A,B,C,D] Current Outcome using ngFor with div and span : Using Div : ...