Table with fixed header with pure html and css

Question:

Well what I try to do is a table with a static header and its body with horizontal scrolling, in its essence I have achieved it, but the width of each column is similar, the width of the first column ID, Price, Stock should be smaller (adapting to its content, which is simply a maximum of 4 digits).

Help me with that please, I thought about giving a size only to the cells that should be smaller (ID, Price, Stock) , but I think that would be wrong.

I would also like the height to be adapted for different screens, but I cannot do it with percentages (I have tried it but I have not been able to, because I think it must be a height specified in pixels). Would it be necessary to use media queries?

* {
  font-family: arial;
}
.header-fixed {
  display: block;
  position: relative;
  height: 100px;
  /*la que necesites*/
  max-height: 80vh;
  /*la que necesites*/
  overflow: auto;
}

.header-fixed thead,
.header-fixed tbody {
  display: block;
}

.header-fixed thead {
  position: sticky;
  display: inline-block;
  top: 0;
}

.header-fixed thead tr > th {
	background: #212529;
	border-color: #32383e;
	color: #fff;
	margin: auto;
	/*padding: 5px 20px 5px 20px;*/
}

.header-fixed tr {
  display: flex;
}

.header-fixed th,
.header-fixed td {
  min-width: 150px;
  /*La que necesites*/
  max-width: 150px;
  /*La que necesites*/
  padding: 0.2em;
}
<table class="header-fixed">
  <thead>
    <tr>
      <th scope='col' class="id">ID</th>
      <th scope='col'>Producto</th>
      <th scope='col'>Precio</th>
      <th scope='col'>Stock</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th scope='row'>1</th>
      <td>Producto 1</td>
      <td>3</td>
      <td class='bag'>
        <span class='badge badge-color'>6</span>
      </td>
    </tr>
    <tr>
      <th scope='row'>13</th>
      <td>Producto 2</td>
      <td>3</td>
      <td class='bag'>
        <span class='badge badge-color'>6</span>
      </td>
    </tr>
    <tr>
      <th scope='row'>21</th>
      <td>Producto 3</td>
      <td>3</td>
      <td class='bag'>
        <span class='badge badge-color'>6</span>
      </td>
    </tr>
    <tr>
      <th scope='row'>...</th>
      <td>Producto ...</td>
      <td>3</td>
      <td class='bag'>
        <span class='badge badge-color'>6</span>
      </td>
    </tr>
  </tbody>
</table>

Answer:

You can use the em unit of measure so that the cells have a minimum width of four letters M and delete the part in which a fixed height is established for the table in .header-fixed { ... height: 10px; ...} . In the example I use a maximum height of 100% so that it depends on the size of the parent element, but if the structure of the page allows it, you can use vh .

I also added those three styles in *{} that usually avoid annoying mismatches in measurements.

    * {
    font-family: arial;
    margin:0px;
    padding:0px;
    box-sizing: border-box;
  }
  body{
    height: 100vh;
  }
  .header-fixed {
    display: block;
    position: relative;
    max-height: 100%;
    overflow: auto;
  }
  .header-fixed thead,
  .header-fixed tbody {
    display: block;
  }
  .header-fixed thead {
    position: sticky;
    display: inline-block;
    top: 0;
    width: 100%;
  }
  .header-fixed thead tr > th {
  	background: #212529;
  	border-color: #32383e;
  	color: #fff;
  	margin: auto;
  }
  .header-fixed tr {
    display: flex;
  }
  .header-fixed th,
  .header-fixed td {
    width: 4em;
    padding: 0.2em;
  }
  td:nth-child(2),
  th:nth-child(2){
    /* tamaño de ID, Precio y Stock fijos (4em c/u) */
    width: calc(100% - 12em);
  }
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <body>
  <table class="header-fixed">
  <thead>
    <tr>
      <th scope='col' class="id">ID</th>
      <th scope='col'>Producto</th>
      <th scope='col'>Precio</th>
      <th scope='col'>Stock</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th scope='row'>1</th>
      <td>Producto 1</td>
      <td>3</td>
      <td class='bag'>
        <span class='badge badge-color'>6</span>
      </td>
    </tr>
    <tr>
      <th scope='row'>13</th>
      <td>Producto 2</td>
      <td>3</td>
      <td class='bag'>
        <span class='badge badge-color'>6</span>
      </td>
    </tr>
    <tr>
      <th scope='row'>13</th>
      <td>Producto 2</td>
      <td>3</td>
      <td class='bag'>
        <span class='badge badge-color'>6</span>
      </td>
    </tr>
    <tr>
      <th scope='row'>13</th>
      <td>Producto 2</td>
      <td>3</td>
      <td class='bag'>
        <span class='badge badge-color'>6</span>
      </td>
    </tr>
    <tr>
      <th scope='row'>13</th>
      <td>Producto 2</td>
      <td>3</td>
      <td class='bag'>
        <span class='badge badge-color'>6</span>
      </td>
    </tr>
    <tr>
      <th scope='row'>13</th>
      <td>Producto 2</td>
      <td>3</td>
      <td class='bag'>
        <span class='badge badge-color'>6</span>
      </td>
    </tr>
    <tr>
      <th scope='row'>13</th>
      <td>Producto 2</td>
      <td>3</td>
      <td class='bag'>
        <span class='badge badge-color'>6</span>
      </td>
    </tr>
    <tr>
      <th scope='row'>13</th>
      <td>Producto 2</td>
      <td>3</td>
      <td class='bag'>
        <span class='badge badge-color'>6</span>
      </td>
    </tr>
    <tr>
      <th scope='row'>13</th>
      <td>Producto 2</td>
      <td>3</td>
      <td class='bag'>
        <span class='badge badge-color'>6</span>
      </td>
    </tr>
    <tr>
      <th scope='row'>13</th>
      <td>Producto 2</td>
      <td>3</td>
      <td class='bag'>
        <span class='badge badge-color'>6</span>
      </td>
    </tr>
    <tr>
      <th scope='row'>13</th>
      <td>Producto 2</td>
      <td>3</td>
      <td class='bag'>
        <span class='badge badge-color'>6</span>
      </td>
    </tr>
    <tr>
      <th scope='row'>13</th>
      <td>Producto 2</td>
      <td>3</td>
      <td class='bag'>
        <span class='badge badge-color'>6</span>
      </td>
    </tr>
    <tr>
      <th scope='row'>13</th>
      <td>Producto 2</td>
      <td>3</td>
      <td class='bag'>
        <span class='badge badge-color'>6</span>
      </td>
    </tr>
    <tr>
      <th scope='row'>13</th>
      <td>Producto 2</td>
      <td>3</td>
      <td class='bag'>
        <span class='badge badge-color'>6</span>
      </td>
    </tr>
    <tr>
      <th scope='row'>13</th>
      <td>Producto 2</td>
      <td>3</td>
      <td class='bag'>
        <span class='badge badge-color'>6</span>
      </td>
    </tr>
    <tr>
      <th scope='row'>13</th>
      <td>Producto 2</td>
      <td>3</td>
      <td class='bag'>
        <span class='badge badge-color'>6</span>
      </td>
    </tr>
    <tr>
      <th scope='row'>13</th>
      <td>Producto 2</td>
      <td>3</td>
      <td class='bag'>
        <span class='badge badge-color'>6</span>
      </td>
    </tr>
    <tr>
      <th scope='row'>13</th>
      <td>Producto 2</td>
      <td>3</td>
      <td class='bag'>
        <span class='badge badge-color'>6</span>
      </td>
    </tr>
    <tr>
      <th scope='row'>13</th>
      <td>Producto 2</td>
      <td>3</td>
      <td class='bag'>
        <span class='badge badge-color'>6</span>
      </td>
    </tr>
    <tr>
      <th scope='row'>13</th>
      <td>Producto 2</td>
      <td>3</td>
      <td class='bag'>
        <span class='badge badge-color'>6</span>
      </td>
    </tr>
    <tr>
      <th scope='row'>13</th>
      <td>Producto 2</td>
      <td>3</td>
      <td class='bag'>
        <span class='badge badge-color'>6</span>
      </td>
    </tr>
    <tr>
      <th scope='row'>13</th>
      <td>Producto 2</td>
      <td>3</td>
      <td class='bag'>
        <span class='badge badge-color'>6</span>
      </td>
    </tr>
    <tr>
      <th scope='row'>21</th>
      <td>Producto 3</td>
      <td>3</td>
      <td class='bag'>
        <span class='badge badge-color'>6</span>
      </td>
    </tr>
    <tr>
      <th scope='row'>21</th>
      <td>Producto 3</td>
      <td>3</td>
      <td class='bag'>
        <span class='badge badge-color'>6</span>
      </td>
    </tr><tr>
      <th scope='row'>21</th>
      <td>Producto 3</td>
      <td>3</td>
      <td class='bag'>
        <span class='badge badge-color'>6</span>
      </td>
    </tr><tr>
      <th scope='row'>21</th>
      <td>Producto 3</td>
      <td>3</td>
      <td class='bag'>
        <span class='badge badge-color'>6</span>
      </td>
    </tr><tr>
      <th scope='row'>21</th>
      <td>Producto 3</td>
      <td>3</td>
      <td class='bag'>
        <span class='badge badge-color'>6</span>
      </td>
    </tr><tr>
      <th scope='row'>21</th>
      <td>Producto 3</td>
      <td>3</td>
      <td class='bag'>
        <span class='badge badge-color'>6</span>
      </td>
    </tr><tr>
      <th scope='row'>21</th>
      <td>Producto 3</td>
      <td>3</td>
      <td class='bag'>
        <span class='badge badge-color'>6</span>
      </td>
    </tr><tr>
      <th scope='row'>21</th>
      <td>Producto 3</td>
      <td>3</td>
      <td class='bag'>
        <span class='badge badge-color'>6</span>
      </td>
    </tr><tr>
      <th scope='row'>21</th>
      <td>Producto 3</td>
      <td>3</td>
      <td class='bag'>
        <span class='badge badge-color'>6</span>
      </td>
    </tr><tr>
      <th scope='row'>21</th>
      <td>Producto 3</td>
      <td>3</td>
      <td class='bag'>
        <span class='badge badge-color'>6</span>
      </td>
    </tr><tr>
      <th scope='row'>21</th>
      <td>Producto 3</td>
      <td>3</td>
      <td class='bag'>
        <span class='badge badge-color'>6</span>
      </td>
    </tr><tr>
      <th scope='row'>21</th>
      <td>Producto 3</td>
      <td>3</td>
      <td class='bag'>
        <span class='badge badge-color'>6</span>
      </td>
    </tr><tr>
      <th scope='row'>21</th>
      <td>Producto 3</td>
      <td>3</td>
      <td class='bag'>
        <span class='badge badge-color'>6</span>
      </td>
    </tr><tr>
      <th scope='row'>21</th>
      <td>Producto 3</td>
      <td>3</td>
      <td class='bag'>
        <span class='badge badge-color'>6</span>
      </td>
    </tr><tr>
      <th scope='row'>21</th>
      <td>Producto 3</td>
      <td>3</td>
      <td class='bag'>
        <span class='badge badge-color'>6</span>
      </td>
    </tr><tr>
      <th scope='row'>21</th>
      <td>Producto 3</td>
      <td>3</td>
      <td class='bag'>
        <span class='badge badge-color'>6</span>
      </td>
    </tr><tr>
      <th scope='row'>21</th>
      <td>Producto 3</td>
      <td>3</td>
      <td class='bag'>
        <span class='badge badge-color'>6</span>
      </td>
    </tr><tr>
      <th scope='row'>21</th>
      <td>Producto 3</td>
      <td>3</td>
      <td class='bag'>
        <span class='badge badge-color'>6</span>
      </td>
    </tr>
    <tr>
      <th scope='row'>...</th>
      <td>Producto ...</td>
      <td>3</td>
      <td class='bag'>
        <span class='badge badge-color'>6</span>
      </td>
    </tr>
  </tbody>
</table>
</body>
</html>

Edit: I was testing it and when the width of some td changes, the table gets messed up. I add th / td:nth-child(2){} to make up for it. I solved it by giving a fixed width to all the columns except the second one that uses calc() to determine the space that is available and occupy it.

Scroll to Top