Search code examples
htmlcsshtml-tabledropdown

Prevent td Element From Growing to Fit Child Elements


I am trying to make a table with drop-down info tabs that appear when you scroll over a term. My initial approach was to make these info tabs not display with display : none css rule, then when the user hovers the mouse over the corresponding text, the the info tab appears by altering display property to display: block.

My problem is that I can't figure out how to override the default behavior for the containing/parent element, and the table resizes to fit the newly appeared element, then resizes back to normal when the user scrolls away. I experimented with z-index (setting the td to z-index: 1 and info tab to z-index:2) as well as visibility:hidden -> visibility:visible vs display:none -> display:block, but no luck with either of those. I also tried setting the max height of the td element to 200px, but it seems to grow past that regardless.

Here is the source code for what i have so far:

/* In an attempt to prevent row from expanding automatically */

td {
  max-height: 100px;
}

.card-body {
  display: none;
  border: 2px solid black;
  height: 300px;
  width: 400px;
  z-index: 2;
}

.card-trigger:hover+.card-body {
  display: inline-block;
  position: relative;
  top: 0px;
  right: 15px;
}

.card-body:hover {
  display: block;
}

.card-body .game-info {
  display: none;
}

.card-body .dd-trigger:hover+.game-info {
  display: block;
}
<h3>Ratings by som bol</h3>
<p>sort by release date (asc/desc), rating amout, game category, game creator, game console</p>
<input type="text" placeholder="filter by game title, categories, creators, consoles, console makers">
<div>Search hints</div>
<table class="table">
  <thead>
    <tr>
      <th>Game title</th>
      <th>your rating</th>
      <th>Average rating</th>
      <th></th>
    </tr>
  </thead>
  <tbody>
    <!-- Row 1 -->
    <tr>
      <td>
        <a class="card-trigger" href="#">Some Videogame</a>
        <div class="card-body">

          <img src="#" alt="picture of the game in question" />
          <h3><a [routerLink]="">Game title</a></h3>
          <p>Some stuff happens and you have fun</p>
          <span class="dd-trigger">Show more info</span>
          <ul class="game-info">
            <li>Average Rating: </li>
            <li>Average Review Score: </li>
          </ul>
        </div>
      </td>

      <td>
        your rating : 2
      </td>
      <td>
        average rating : 3
      </td>
      <td><button>Delete rating</button></td>
    </tr>
    <!-- Row 2 -->
    <tr>
      <td>
        <a class="card-trigger" href="#">Some Videogame</a>
        <div class="card-body">

          <img src="#" alt="picture of the game in question" />
          <h3><a [routerLink]="">Game title</a></h3>
          <p>Some stuff happens and you have fun</p>
          <span class="dd-trigger">Show more info</span>
          <ul class="game-info">
            <li>Average Rating: </li>
            <li>Average Review Score: </li>
          </ul>
        </div>
      </td>

      <td>
        your rating : 2
      </td>
      <td>
        average rating : 3
      </td>
      <td><button>Delete rating</button></td>
    </tr>
    <!-- row 3 -->
    <tr>
      <td>
        <a class="card-trigger" href="#">Some Videogame</a>
        <div class="card-body">

          <img src="#" alt="picture of the game in question" />
          <h3><a [routerLink]="">Game title</a></h3>
          <p>Some stuff happens and you have fun</p>
          <span class="dd-trigger">Show more info</span>
          <ul class="game-info">
            <li>Average Rating: </li>
            <li>Average Review Score: </li>
          </ul>
        </div>
      </td>

      <td>
        your rating : 2
      </td>
      <td>
        average rating : 3
      </td>
      <td><button>Delete rating</button></td>
    </tr>
  </tbody>
</table>


Solution

  • In order to prevent parents from resizing to fit the contained element, you must do three things:

    1. Set parent position to relative
    2. Set child position to absolute (and position in appropriate place using top, bottom, left, right)
    3. Set child element z-index higher than that of parent. We do this to prevent any parent styles from overlapping with child styles. It essentially makes the child element look like it is sitting on top of the parent element.

    the html is a trivial example of a table with one row. the css hides the contained child div by default, and sets the display to block when hovering, in addition to default styles and the positioning/z-index mentioned above

    table, th, td {
      border: 1px solid black;
    }
    
    .pop-up {
      display: none
    }
    
    td {
      position: relative;
    }
    
    td:hover > .pop-up {
      display: block;
    }
    
    .pop-up {
      width: 500px;
      height: 100px;
      background: red;
      border: 1px solid black;
      position: absolute;
      left: 50px;
      z-index: 1;  
    }
    

    click here to see full example