Search code examples
htmlcsstailwind-css

Alling a menu to the right of a button positioned in a table column


I have a webpage with a table in which the last column is a button that opens a dropdown menu (for simplicity, the example does not include JS):

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdn.tailwindcss.com"></script>
    <style>
        .butonMenu {
            display: inline-flex;
            align-items: center;
            border-width: 1px;
            padding: 0.25rem;
            text-align: center;
            font-size: 1rem;
            line-height: 1.25rem;
        }

        .menu{
            position: absolute;
            z-index: 10;
            margin-top: 0.25rem;
            display: grid;
            width: max-content;
            max-width: 32rem;
            grid-auto-flow: row;
            gap: 0.25rem;
            background-color: whitesmoke;
        }

        .menuOption {
            display: inline-flex;
            width: 100%;
            align-items: center;
            padding: 0.25rem;
            text-align: center;
            font-size: 0.875rem;
            line-height: 1.25rem;
            font-weight: 500;
        }
    </style>
</head>

<body>
    <table
        class="shadow-3xl sm:rounded-lg border border-neutral-200 text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400">
        <tr>
            <th>Col1</th>
            <th>Col2</th>
            <th></th>
        </tr>
        <tr class="bg-white border-b dark:bg-gray-800 dark:border-gray-700 hover:bg-blue-100">
            <td class=" w-20">Val1</td>
            <td class=" w-20">Val2</td>
            <td><button type="button" title="Mai multe optiuni" class="butonMenu">...</button>
                <div class="menu">
                    <button type="button" class="menuOption ">Option1</button>
                    <button type="button" class="menuOption ">Option2</button>
                    <button type="button" class="menuOption ">Option3</button>

                </div>
            </td>
        </tr>
    </table>
</body>

</html>

This is what menu looks like:

incorrect menu alignment

And this is what I want it to look like:

enter image description here

I want the right side of the menu to aling with the right side of the button or the cell in which the button is situated.

I could achieve this effect by adding a negative margin to the menu class:

margin-left: -40px;

The problem with this approach is that the values of the menu options are dynamic, and they can change from page to page.

I know I can monitor the width of the menu with JS and update the CSS, but I wondered if there is a more simple and elegant solution.

If this is impossible using only CSS, I am open to simple JS methods (I used the ResizeObserver object from Vue.js to monitor the width but it feels to complicated for such a minute problem)


Solution

  • To achieve the result you showed in that second picture, you may use position: relative on the td container and then set right: 0 on the .menu element.

    This is your code with such corrections:

    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <script src="https://cdn.tailwindcss.com"></script>
      <style>
        .butonMenu {
          display: inline-flex;
          align-items: center;
          border-width: 1px;
          padding: 0.25rem;
          text-align: center;
          font-size: 1rem;
          line-height: 1.25rem;
        }
        
        .menu_container{
          position: relative;
        }
        
        .menu {
          right: 0;    
          position: absolute;
          z-index: 10;
          margin-top: 0.25rem;
          display: grid;
          width: max-content;
          max-width: 32rem;
          grid-auto-flow: row;
          gap: 0.25rem;
          background-color: whitesmoke;
        }
        
        .menuOption {
          display: inline-flex;
          width: 100%;
          align-items: center;
          padding: 0.25rem;
          text-align: center;
          font-size: 0.875rem;
          line-height: 1.25rem;
          font-weight: 500;
        }
      </style>
    </head>
    
    <body>
      <table class="shadow-3xl sm:rounded-lg border border-neutral-200 text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400">
        <tr>
          <th>Col1</th>
          <th>Col2</th>
          <th></th>
        </tr>
        <tr class="bg-white border-b dark:bg-gray-800 dark:border-gray-700 hover:bg-blue-100">
          <td class=" w-20">Val1</td>
          <td class=" w-20">Val2</td>
          <td class="menu_container">
            <button type="button" title="Mai multe optiuni" class="butonMenu">...</button>
            <div class="menu">
              <button type="button" class="menuOption ">Option1</button>
              <button type="button" class="menuOption ">Option2</button>
              <button type="button" class="menuOption ">Option3</button>
    
            </div>
          </td>
        </tr>
      </table>
    </body>
    
    </html>