Muhi Logo Text
Work With MeAboutTestimonialsBlog

How to Create a Responsive Table with React

Learn how to create a responsive and user-friendly table on mobile and tablet devices using React

Last updated on March 17, 2024

react
html
React Responsive Table

In web development, tables are a core element for displaying tabular data, integral to numerous projects and applications. However, traditional HTML tables don’t automatically adjust to different screen sizes, which could cause usability issues in mobile and tablet environments.

This tutorial will cover two practical approaches to creating a responsive table in React applications.

  • Table Scroll: This approach involves adding horizontal scrolling to tables on smaller screens.

  • Altering Table Layout: This method includes hiding the table header and rearranging the table cells so that headers and cells are displayed vertically in each row.

Creating a Basic Table

Before we dive into making our table responsive, let’s begin by constructing a bare table in React. We will create a table to display a list of student records. Each record will include the following information:

  • Student ID
  • Name
  • Date of Birth
  • Major

Step 1: Define the Data

First, we need to define our data. We’ll create an array of student records that we’ll use to populate the table. Each record will be an object with properties corresponding to the table’s columns.

const students = [
  {
    id: 1,
    name: "Alice Johnson",
    dob: "2001-04-15",
    major: "Computer Science",
  },
  { id: 2, name: "Bob Smith", dob: "2000-09-08", major: "Mathematics" },
  { id: 3, name: "Carol Williams", dob: "1999-02-23", major: "Physics" },
  // Add more student records as needed
];

Step 2: Build the Table Component

Next, let’s create a table component that loops through this data and displays each student’s details in a row.

const StudentTable = () => {
  return (
    <table>
      <thead>
        <tr>
          <th>Student ID</th>
          <th>Name</th>
          <th>Date of Birth</th>
          <th>Major</th>
        </tr>
      </thead>
      <tbody>
        {students.map(student => (
          <tr key={student.id}>
            <td>{student.id}</td>
            <td>{student.name}</td>
            <td>{student.dob}</td>
            <td>{student.major}</td>
          </tr>
        ))}
      </tbody>
    </table>
  );
};

Step 3: Styling the Table

To ensure our table is functional and visually appealing, we’ll add some basic CSS styling. This will include setting a font family, adding borders to the table and rows, alternating the background color of rows for better readability, and ensuring proper padding for text.

table {
  font-family: Arial, sans-serif;
  border-collapse: collapse;
  width: 100%;
  border: 1px solid #ddd;
}

tr {
  border-bottom: 1px solid #ccc;
}

th,
td {
  text-align: left;
  padding: 8px;
}

tr:nth-child(even) {
  background-color: #f2f2f2;
}

In this basic example, if we try to resize the window using the resize handle in the bottom right corner, the table doesn’t adjust to the smaller screen size.

Creating a Responsive Scroll Table

When it comes to enhancing a responsive table on smaller screens, implementing a horizontal scroll is a straightforward and effective solution. This approach maintains the layout’s consistency and allows users to view all columns by scrolling horizontally. Let’s go through the steps to create a scrollable table container.

Step 1: Add a Scrollable Container

First, we need to wrap our table with a container because the table element itself cannot be made scrollable directly. We create a “ghost” container around the table to enable scrolling.

const ScrollableTableContainer = () => {
  return (
    <div className="table-container">
      <StudentTable />
    </div>
  );
};

Step 2: CSS for Horizontal Scrolling

Next, we’ll add CSS to trigger a horizontal scrollbar when the table exceeds the viewport’s width. We do this by setting the overflow-x property to auto.

... 

.table-container {
  overflow-x: auto;
}

Step 3: Prevent Text Wrapping

Finally, to prevent the text within each table cell from wrapping and ensure a consistent layout as the user scrolls horizontally, we’ll set white-space: nowrap on the table cells.

... 

th,
td {
  white-space: nowrap;
}

Here is the complete code for the scrollable table container:

.table-container {
  overflow-x: auto;
}

table {
  font-family: Arial, sans-serif;
  border-collapse: collapse;
  width: 100%;
  border: 1px solid #ddd;
}
tr {
  border-bottom: 1px solid #ccc;
}
th,
td {
  text-align: left;
  padding: 8px;
  white-space: nowrap;
}
tr:nth-child(even) {
  background-color: #f2f2f2;
}
import "./App.css";

const students = [
  {
    id: 1,
    name: "Alice Johnson",
    dob: "2001-04-15",
    major: "Computer Science",
  },
  { id: 2, name: "Bob Smith", dob: "2000-09-08", major: "Mathematics" },
  { id: 3, name: "Carol Williams", dob: "1999-02-23", major: "Physics" },
  // Add more student records as needed
];

const StudentTable = () => {
  return (
    <table>
      <thead>
        <tr>
          <th>Student ID</th>
          <th>Name</th>
          <th>Date of Birth</th>
          <th>Major</th>
        </tr>
      </thead>
      <tbody>
        {students.map(student => (
          <tr key={student.id}>
            <td>{student.id}</td>
            <td>{student.name}</td>
            <td>{student.dob}</td>
            <td>{student.major}</td>
          </tr>
        ))}
      </tbody>
    </table>
  );
};

const ScrollableTableContainer = () => {
  return (
    <div className="table-container">
      <StudentTable />
    </div>
  );
};

export default function App() {
  return <ScrollableTableContainer />;
}

Altering Table Layout

We can alter the table’s layout for a more mobile-friendly design that eliminates the need for horizontal scrolling. This approach involves hiding the table headers and changing the data cells of each row to stack vertically instead of horizontally. Let’s go through the necessary steps to achieve this:

Step 1: Hide Table Headers on Small Screens

First, we’ll use a CSS media query to hide the table headers when the screen size is at or below a certain width, typically that of a small tablet or a mobile phone.

...

@media screen and (max-width: 600px) {
  th {
    display: none;
  }
}

Step 2: Change Data Cell Display on Small Screens

Next, we need to adjust the display of the table cells (td) in the table body. On smaller screens, we’ll change their display from table-cell to flex. This change allows the data to stack on top of each other within each row, making it more readable on mobile devices.

...

@media screen and (max-width: 600px) {
  ...

  td {
    display: flex;
  }
}

Step 3: Add Header Names to Each Cell

Since we removed the main table headers, we’ll add a label to each cell indicating what data it represents. These labels will only be visible on small screens and act as a substitute for the table headers. Also, the styling should be updated to make the labels and data more distinguishable.

const StudentTableResponsive = () => {
  return (
    <table>
      <thead>
        <tr>
          <th>Student ID</th>
          <th>Name</th>
          <th>Date of Birth</th>
          <th>Major</th>
        </tr>
      </thead>
      <tbody>
        {students.map(student => (
          <tr key={student.id}>
            <td>
              <span className="cell-header">Student ID:</span> {student.id}
            </td>
            <td>
              <span className="cell-header">Name:</span> {student.name}
            </td>
            <td>
              <span className="cell-header">Date of Birth:</span> {student.dob}
            </td>
            <td>
              <span className="cell-header">Major:</span> {student.major}
            </td>
          </tr>
        ))}
      </tbody>
    </table>
  );
};
... 

.cell-header {
  display: none;
}

@media screen and (max-width: 600px) {
  ... 
  
  .cell-header {
    display: block;
    font-weight: bold;
  }
  td {
    display: flex;
    justify-content: space-between;
  }
}

Here is the complete code for the responsive table layout:

table {
  font-family: Arial, sans-serif;
  border-collapse: collapse;
  width: 100%;
  border: 1px solid #ddd;
}
tr {
  border-bottom: 1px solid #ccc;
}
th,
td {
  text-align: left;
  padding: 8px;
  white-space: nowrap;
}
tr:nth-child(even) {
  background-color: #f2f2f2;
}

.cell-header {
  display: none;
}

@media screen and (max-width: 600px) {
  th {
    display: none;
  }
  .cell-header {
    display: block;
    font-weight: bold;
  }
  td {
    display: flex;
    justify-content: space-between;
  }
}
import './App.css';

const students = [
  {
    id: 1,
    name: 'Alice Johnson',
    dob: '2001-04-15',
    major: 'Computer Science',
  },
  { id: 2, name: 'Bob Smith', dob: '2000-09-08', major: 'Mathematics' },
  { id: 3, name: 'Carol Williams', dob: '1999-02-23', major: 'Physics' },
  // Add more student records as needed
];

const StudentTableResponsive = () => {
  return (
    <table>
      <thead>
        <tr>
          <th>Student ID</th>
          <th>Name</th>
          <th>Date of Birth</th>
          <th>Major</th>
        </tr>
      </thead>
      <tbody>
        {students.map((student) => (
          <tr key={student.id}>
            <td>
              <span className="cell-header">Student ID:</span> {student.id}
            </td>
            <td>
              <span className="cell-header">Name:</span> {student.name}
            </td>
            <td>
              <span className="cell-header">Date of Birth:</span> {student.dob}
            </td>
            <td>
              <span className="cell-header">Major:</span> {student.major}
            </td>
          </tr>
        ))}
      </tbody>
    </table>
  );
};

export default function App() {
  return <StudentTableResponsive />;
}

With these steps, we now have a responsive table layout that is significantly more user-friendly for mobile viewers. If we resize the window using the resize handle in the bottom right corner, we can see that the table layout changes to a more mobile-friendly format when the screen size is reduced.

Summary & Complete Code

In this tutorial, we reviewed some essential techniques for creating a responsive table in React. We explored two practical approaches: implementing a scrollable table for smaller screens and altering the table layout for enhanced mobile friendliness. These strategies not only maintain data accessibility but also improve user experience across various devices.

Here is the complete code example on StackBlitz:

Bye for now 👋

If you enjoyed this post, I regularly share similar content on Twitter. Follow me @muhimasri to stay up to date, or feel free to message me on Twitter if you have any questions or comments. I'm always open to discussing the topics I write about!

Recommended Reading

Learn how to create a scrollable table with a sticky header and column in React.

react
html
css

Discussion

Upskill Your Frontend Development Techniques 🌟

Subscribe to stay up-to-date and receive quality front-end development tutorials straight to your inbox!

No spam, sales, or ads. Unsubscribe anytime you wish.

© 2024, Muhi Masri