position: sticky Does not work inside a container with overflow-auto in a dynamically created table using Tailwind CSS + Preline JS [closed]

I’m working on a project where I’m dynamically creating a large table using JavaScript and Tailwind CSS. I need certain headers and columns to stay “sticky” while scrolling horizontally and vertically. However, I’m facing an issue:

When I wrap the table in a div with the overflow-auto class, the position: sticky property stops working for the headers and columns. If I remove the overflow-auto class, the sticky positioning works correctly, but I lose the scrollbars, which are necessary because of the table’s size.

Here’s my code:

<div class="bg-white border-t border-gray-200 overflow-auto">
    <table id="graph" class="w-full divide-y divide-gray-200">
        <thead class="bg-gray-50">
            <tr class="divide-x" id="table1-months-headers">
                <th class="sticky top-0 left-0 z-50 bg-gray-50"></th>
                <th class="sticky top-0 left-[50px] z-50 bg-gray-50"></th>
            </tr>
            <tr class="divide-x" id="table2-headers">
                <th scope="col" class="sticky top-[40px] left-0 z-50 bg-gray-50 border-t border-gray-200 px-2 text-center whitespace-nowrap">
                    <span class="text-xs font-semibold uppercase tracking-wide text-gray-800">ID</span>
                </th>
                <th scope="col" id="name" class="sticky top-[40px] left-[50px] z-50 min-w-[200px] bg-gray-50 border-t border-gray-200 px-2 text-start whitespace-nowrap">
                    <div class="flex items-center gap-1">
                        <span class="text-xs font-semibold uppercase tracking-wide text-gray-800">Name</span>
                    </div>
                </th>
                <!-- Other headers -->
            </tr>
        </thead>
        <tbody>
            <!-- Dynamically generated table rows -->
        </tbody>
    </table>
</div>

I’m generating table headers and cells dynamically. Here’s how I’m adding the headers:

const monthsHeaders = $('#table1-months-headers');

let tdHeaders = `
    <td class="px-2 text-center whitespace-nowrap bg-gray-50 border-b border-gray-200">
        <span class="text-xs font-semibold uppercase tracking-wide text-gray-800">Total</span>
    </td>
`;

monthsHeaders.append(tdHeaders);

months.forEach(month => {
    let td = `<td class="sticky top-0 z-20 px-6 py-2 text-center whitespace-nowrap bg-gray-50 border-b border-gray-200" colspan="${month.days}">
                <span class="upper-month text-xs font-semibold uppercase tracking-wide text-gray-800">${month.name}</span>
            </td>`;
    monthsHeaders.append(td);
});

const tableHeaders = $('#table2-headers');
tableHeaders.append(tdHeaders);

months.forEach(month => {
    for (let i = 1; i <= month.days; i++) {
        let th = `<th scope="col" class="sticky top-[40px] z-30 min-w-8 max-w-12 whitespace-nowrap bg-gray-50" data-date="${year}-${month.code}-${String(i).padStart(2, '0')}">
                    <span class="text-xs font-semibold uppercase tracking-wide">${i}</span>
                </th>`;
        tableHeaders.append(th);
    }
});

What I’ve tried so far:

Parent container adjustments: Ensured correct position properties (relative, static, etc.) on parent elements.
Changing overflow properties: Tried various combinations of overflow properties on parent elements, like overflow-x, overflow-y, but the issue persists.
Restructuring HTML: Tried different HTML structures to see if a different hierarchy would help, but no luck.