Search code examples
csstailwind-css

Horizontal scroll conflict when sibling element has display:block


When adding overflow-x-auto to horizontally scroll in the contents causes the table to overflow outside of contents and scroll is in the viewport. This happens when the sidebar is open with display block. However, when you go to mobile or remove the sidebar, the scroll on contents work as intended. How to fix the scrolling of contents when sidebar is open?

Note1: This is as compact as I can do update the code.

Note2: To fully view the issue, you may need to click on the full page when running snippet and zoom in.

the problem

<script src="https://cdn.tailwindcss.com/3.4.14"></script>
<body class="font-sans antialiased">
    <div class="flex h-screen bg-red-50 dark:bg-red-900">
        <!-- sidebar -->
        <aside class="z-20 hidden w-64 overflow-y-auto bg-white dark:bg-gray-800 md:block flex-shrink-0">
            <div class="py-4 text-gray-500 dark:text-gray-400">
                <a class="ml-6 text-lg font-bold text-gray-800 dark:text-gray-200">
                    APP
                </a>
            </div>
        </aside>

        <!-- contents -->
        <div class="flex flex-col flex-1 w-full">
            <main class="h-full overflow-y-auto">
                <div class="py-12">
                    <div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
                        <div class="bg-blue-50 overflow-hidden shadow-sm sm:rounded-lg overflow-x-auto max-w-full">
                            <div class="p-6 text-gray-900">
                                <table class="table-fixed w-full">
                                    <thead>
                                        <tr class="bg-gray-100">
                                            <th class="px-4 py-2 w-20">No.</th>
                                            <th class="px-4 py-2 w-52">Name</th>
                                            <th class="px-4 py-2 w-52">Address</th>
                                            <th class="px-4 py-2 w-44">Action</th>
                                        </tr>
                                    </thead>
                                    <tbody>
                                        <tr>
                                            <td class="border px-4 py-2">1</td>
                                            <td class="border px-4 whitespace-nowrap py-2">
                                                name1
                                            </td>
                                            <td class="border px-4 whitespace-nowrap py-2">
                                                address 1
                                            </td>
                                            <td lass="border px-4 py-2 flex gap-2 items-center justify-between">
                                            </td>
                                        </tr>
                                        <tr>
                                            <td class="border px-4 py-2">1</td>
                                            <td class="border px-4 whitespace-nowrap py-2">
                                                name 2
                                            </td>
                                            <td class="border px-4 whitespace-nowrap py-2">
                                                address 2
                                            </td>
                                            <td lass="border px-4 py-2 flex gap-2 items-center justify-between">
                                            </td>
                                        </tr>
                                    </tbody>
                                </table>
                            </div>
                        </div>
                    </div>
                </div>
            </main>
        </div>
    </div>
</body>


Solution

  • min-width: min-content is implicitly applied to the content <div> due to it being in a horizontal flex layout. This causes this <div> to never shrink below the width of the table, thus, never "activating" the overflow-x: auto on the child element. Instead, it causes the overflow on the root <div>.

    Rather, we'd want to shrink the content <div>, so that the table can overflow the overflow-x-auto element. We can do this by overriding the min-width: min-content with min-width: 0 via the min-w-0 class:

    <script src="https://cdn.tailwindcss.com/3.4.14"></script>
    <body class="font-sans antialiased">
        <div class="flex h-screen bg-red-50 dark:bg-red-900">
            <!-- sidebar -->
            <aside class="z-20 hidden w-64 overflow-y-auto bg-white dark:bg-gray-800 md:block flex-shrink-0">
                <div class="py-4 text-gray-500 dark:text-gray-400">
                    <a class="ml-6 text-lg font-bold text-gray-800 dark:text-gray-200">
                        APP
                    </a>
                </div>
            </aside>
    
            <!-- contents -->
            <div class="flex flex-col flex-1 w-full min-w-0">
                <main class="h-full overflow-y-auto">
                    <div class="py-12">
                        <div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
                            <div class="bg-blue-50 overflow-hidden shadow-sm sm:rounded-lg overflow-x-auto max-w-full">
                                <div class="p-6 text-gray-900">
                                    <table class="table-fixed w-full">
                                        <thead>
                                            <tr class="bg-gray-100">
                                                <th class="px-4 py-2 w-20">No.</th>
                                                <th class="px-4 py-2 w-52">Name</th>
                                                <th class="px-4 py-2 w-52">Address</th>
                                                <th class="px-4 py-2 w-44">Action</th>
                                            </tr>
                                        </thead>
                                        <tbody>
                                            <tr>
                                                <td class="border px-4 py-2">1</td>
                                                <td class="border px-4 whitespace-nowrap py-2">
                                                    name1
                                                </td>
                                                <td class="border px-4 whitespace-nowrap py-2">
                                                    address 1
                                                </td>
                                                <td lass="border px-4 py-2 flex gap-2 items-center justify-between">
                                                </td>
                                            </tr>
                                            <tr>
                                                <td class="border px-4 py-2">1</td>
                                                <td class="border px-4 whitespace-nowrap py-2">
                                                    name 2
                                                </td>
                                                <td class="border px-4 whitespace-nowrap py-2">
                                                    address 2
                                                </td>
                                                <td lass="border px-4 py-2 flex gap-2 items-center justify-between">
                                                </td>
                                            </tr>
                                        </tbody>
                                    </table>
                                </div>
                            </div>
                        </div>
                    </div>
                </main>
            </div>
        </div>
    </body>