skip to Main Content

Is it possible, without JavaScript, to place the table title and some <select> filters to both top edges of the table?

Something like:

My Orders Table                  [Select Year] [Select Month]

------------------------------------------------------------
|     date     |     amount    |          comments         |
------------------------------------------------------------
|   5.5.2020   |      $50      |        some_comment       |
------------------------------------------------------------
|  1.12.2022   |      $10      |        some_comment       |
------------------------------------------------------------
|   1.1.2023   |      $33      |        some_comment       |
------------------------------------------------------------

This is a snippet to show the general elements I need, it has no design at all, just elements that match the above drawing

<p class="table_title"> My Orders Table </p>

<select id='year_select'>
  <option value=''>--Select Year--</option>
  <option value='2014'>2014</option>
  <option value='2015'>2015</option>
  <option value='2016'>2016</option>
  <option value='2017'>2017</option>
  <option value='2018'>2018</option>
  <option value='2019'>2019</option>
  <option value='2020'>2020</option>
  <option value='2021'>2021</option>
  <option value='2022'>2022</option>
  <option value='2023'>2023</option>
</select>

<select id='month_select'>
  <option value=''>--Select Month--</option>
  <option value='1'>January</option>
  <option value='2'>February</option>
  <option value='3'>March</option>
  <option value='4'>April</option>
  <option value='5'>May</option>
  <option value='6'>June</option>
  <option value='7'>July</option>
  <option value='8'>August</option>
  <option value='9'>September</option>
  <option value='10'>October</option>
  <option value='11'>November</option>
  <option value='12'>December</option>
</select>

<table>
  <tr>
    <th>Date</th>
    <th>Amount</th>
    <th>Comment</th>
  </tr>
  <tr>
    <td>5.5.2020</td>
    <td>$50</td>
    <td>some_comment</td>
  </tr>
  <tr>
    <td>1.12.2022</td>
    <td>$10</td>
    <td>some_comment</td>
  </tr>
  <tr>
    <td>1.1.2023</td>
    <td>$33</td>
    <td>some_comment</td>
  </tr>
</table>

The problem for me was that the table in HTML has no constant width and I also want it to be responsive and change width according to the screen size.

So the table width is unknown until the page rendering.

I was not able to make it with flex

2

Answers


  1. Just add that select input inside <tr> at the top of the table.

    table { 
        table-layout:fixed;
        text-align: center;
    }
    
    td { 
        overflow: hidden; 
        text-overflow: ellipsis; 
        word-wrap: break-word;
    }
    <table>
      <tr>
        <td>
          <p class="table_title"> My Orders Table </p>
        </td>
        <td></td>
        <td>
          <select id='year_select'>
            <option value=''>--Select Year--</option>
            <option value='2014'>2014</option>
            <option value='2015'>2015</option>
            <option value='2016'>2016</option>
            <option value='2017'>2017</option>
            <option value='2018'>2018</option>
            <option value='2019'>2019</option>
            <option value='2020'>2020</option>
            <option value='2021'>2021</option>
            <option value='2022'>2022</option>
            <option value='2023'>2023</option>
          </select>
          <select id='month_select'>
            <option value=''>--Select Month--</option>
            <option value='1'>Janaury</option>
            <option value='2'>February</option>
            <option value='3'>March</option>
            <option value='4'>April</option>
            <option value='5'>May</option>
            <option value='6'>June</option>
            <option value='7'>July</option>
            <option value='8'>August</option>
            <option value='9'>September</option>
            <option value='10'>October</option>
            <option value='11'>November</option>
            <option value='12'>December</option>
          </select>
        </td>
      </tr>
      <tr>
        <th>Date</th>
        <th>Amount</th>
        <th>Comment</th>
      </tr>
      <tr>
        <td>5.5.2020</td>
        <td>$50</td>
        <td>some_comment</td>
      </tr>
      <tr>
        <td>1.12.2022</td>
        <td>$10</td>
        <td>some_comment</td>
      </tr>
      <tr>
        <td>1.1.2023</td>
        <td>$33</td>
        <td>some_comment</td>
      </tr>
    </table>
    Login or Signup to reply.
  2. Note that you don’t want to include the filters directly in the table, since they’re neither part of the data nor part of the table headers. You’ll also want to include a <label> for each <select>, as screenreaders won’t know what those fields are for otherwise. E.g. once "2014" is selected, a screenreader will just continue to announce "2014" aloud when that dropdown is focused – rather than e.g. "Filter by Year."

    This also lets us remove the placeholder -- Select Month -- options entirely, although we leave an initial blank one so that a user can still remove an applied filter.

    That being said, here’s one way I might handle this setup, using <figure> and <figcaption> elements to associate the table and its header, and BEM naming conventions for the classes.

    I’ve also made this responsive, and the filters float down underneath the table title at small screen widths.

    .orders {
      --orders-columns: 1;
      display: grid;
      grid-template-columns: repeat(var(--orders-columns), auto);
      column-gap: 2rem;
    }
    
    @media (min-width: 600px) {
      .orders {
        --orders-columns: 2;
      }
    }
    
    .orders__title {
      font-weight: bold;
    }
    
    .orders__filters {
      display: flex;
      align-items: flex-start;
    }
    
    @media (min-width: 600px) {
      .orders__filters {
        justify-content: flex-end;
      }
    }
    
    .orders__filter-label {
      display: block;
      padding-right: 0.5rem;
    }
    
    .orders__filter + .orders__filter-label {
      padding-left: 1rem;
    }
    
    .orders__table {
      grid-column: 1 / -1;
      /* remove browser-default styling so our caption aligns */
      border-collapse: collapse;
    }
    
    .orders__table th {
      text-align: left;
    }
    
    .orders__table th:last-child,
    .orders__table td:last-child {
      /* align ending content with the filters above them */
      text-align: right;
    }
    <figure class='orders'>
      <figcaption class='orders__title'>My Orders Table</figcaption>
      <div class='orders__filters'>
        <label class='orders__filter-label' for='year-select' aria-label='Filter orders by year'>Year</label>
        <select class='orders__filter' name='year-select' id='year-select'>
          <option></option>
          <option value='2014'>2014</option>
          <option value='2015'>2015</option>
          <option value='2016'>2016</option>
          <option value='2017'>2017</option>
          <option value='2018'>2018</option>
          <option value='2019'>2019</option>
          <option value='2020'>2020</option>
          <option value='2021'>2021</option>
          <option value='2022'>2022</option>
          <option value='2023'>2023</option>
        </select>
        <label class='orders__filter-label' for='month-select' aria-label='Filter orders by month'>Month</label>
        <select class='orders__filter' name='month-select' id='month-select'>
          <option></option>
          <option value='1'>Janaury</option>
          <option value='2'>February</option>
          <option value='3'>March</option>
          <option value='4'>April</option>
          <option value='5'>May</option>
          <option value='6'>June</option>
          <option value='7'>July</option>
          <option value='8'>August</option>
          <option value='9'>September</option>
          <option value='10'>October</option>
          <option value='11'>November</option>
          <option value='12'>December</option>
        </select>
      </div>
      <table class='orders__table' aria-live='polite'>
        <thead>
          <th>Date</th>
          <th>Amount</th>
          <th>Comment</th>
        </thead>
        <tbody>
          <tr>
            <td>5.5.2020</td>
            <td>$50</td>
            <td>some_comment</td>
          </tr>
          <tr>
            <td>1.12.2022</td>
            <td>$10</td>
            <td>some_comment</td>
          </tr>
          <tr>
            <td>1.1.2023</td>
            <td>$33</td>
            <td>some_comment</td>
          </tr>
        </tbody>
      </table>
    </figure>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search